Exemplo n.º 1
0
        public ScalarFieldTypeDescription DefaultScalarFieldTypeMapping(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?"
                }
            }
            ;

            valueType = (valueType as GraphQlFieldType)?.UnwrapIfNonNull() ?? valueType;
            if (valueType.Kind == GraphQlTypeKind.Enum)
            {
                return new ScalarFieldTypeDescription {
                           NetTypeName = NamingHelper.ToPascalCase(valueType.Name) + "?"
                }
            }
            ;

            var dataType = valueType.Name == GraphQlTypeBase.GraphQlTypeScalarString ? "string" : "object";

            return(new ScalarFieldTypeDescription {
                NetTypeName = GraphQlGenerator.AddQuestionMarkIfNullableReferencesEnabled(this, dataType)
            });
        }
        private static string ScalarToNetType(GraphQlType baseType, string valueName, GraphQlTypeBase valueType)
        {
            switch (valueType.Name)
            {
            case GraphQlTypeBase.GraphQlTypeScalarInteger:
                return("int?");

            case GraphQlTypeBase.GraphQlTypeScalarByte:
                return("byte?");

            case GraphQlTypeBase.GraphQlTypeScalarString:
                return(GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping(baseType, valueType, valueName));

            case GraphQlTypeBase.GraphQlTypeScalarFloat:
                return("decimal?");

            case GraphQlTypeBase.GraphQlTypeScalarBoolean:
                return("bool?");

            case GraphQlTypeBase.GraphQlTypeScalarId:
                return("Guid?");

            case GraphQlTypeBase.GraphQlTypeScalarDateTime:
                return("DateTime?");

            default:
                return(GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping(baseType, valueType, valueName));
            }
        }
        private static string ScalarToNetType(GraphQlType baseType, string valueName, GraphQlTypeBase valueType)
        {
            switch (valueType.Name)
            {
            case GraphQlTypeBase.GraphQlTypeScalarInteger:
                return(GetIntegerNetType());

            case GraphQlTypeBase.GraphQlTypeScalarString:
                return(GetCustomScalarType(baseType, valueType, valueName));

            case GraphQlTypeBase.GraphQlTypeScalarFloat:
                return(GetFloatNetType());

            case GraphQlTypeBase.GraphQlTypeScalarBoolean:
                return("bool?");

            case GraphQlTypeBase.GraphQlTypeScalarDateTime:
                return("DateTime?");

            case GraphQlTypeBase.GraphQlTypeScalarId:
                return(GetIdNetType());

            default:
                return(GetCustomScalarType(baseType, valueType, valueName));
            }
        }
 private static void GenerateDataClassBody(GraphQlType type, StringBuilder builder)
 {
     foreach (var field in type.Fields.Where(f => !f.IsDeprecated || GraphQlGeneratorConfiguration.IncludeDeprecatedFields))
     {
         GenerateDataProperty(type, field, field.IsDeprecated, field.DeprecationReason, builder);
     }
 }
        private static void FindAllReferencedObjectTypes(GraphQlSchema schema, GraphQlType type, ISet <string> objectTypes)
        {
            foreach (var member in (IEnumerable <IGraphQlMember>)type.InputFields ?? type.Fields)
            {
                var         unwrappedType = member.Type.UnwrapIfNonNull();
                GraphQlType memberType;
                switch (unwrappedType.Kind)
                {
                case GraphQlTypeKindObject:
                    objectTypes.Add(unwrappedType.Name);
                    memberType = schema.Types.Single(t => t.Name == unwrappedType.Name);
                    FindAllReferencedObjectTypes(schema, memberType, objectTypes);
                    break;

                case GraphQlTypeKindList:
                    var itemType = unwrappedType.OfType.UnwrapIfNonNull();
                    if (IsComplexType(itemType.Kind))
                    {
                        memberType = schema.Types.Single(t => t.Name == itemType.Name);
                        FindAllReferencedObjectTypes(schema, memberType, objectTypes);
                    }

                    break;
                }
            }
        }
        private static void GenerateEnum(GraphQlType type, StringBuilder builder)
        {
            builder.Append("public enum ");
            builder.AppendLine(type.Name);
            builder.AppendLine("{");

            var enumValues = type.EnumValues.ToList();

            for (var i = 0; i < enumValues.Count; i++)
            {
                var enumValue = enumValues[i];
                GenerateCodeComments(builder, enumValue.Description);
                builder.Append("    ");
                var netIdentifier = NamingHelper.ToNetEnumName(enumValue.Name);
                if (netIdentifier != enumValue.Name)
                {
                    builder.Append($"[EnumMember(Value=\"{enumValue.Name}\")] ");
                }

                builder.Append(netIdentifier);

                if (i < enumValues.Count - 1)
                {
                    builder.Append(",");
                }

                builder.AppendLine();
            }

            builder.AppendLine("}");
        }
        private static string BuildMethodParameterDefinition(GraphQlType baseType, GraphQlArgument argument)
        {
            var isNotNull       = argument.Type.Kind == GraphQlTypeKindNonNull;
            var unwrappedType   = UnwrapNonNull(argument.Type);
            var argumentNetType = unwrappedType.Kind == GraphQlTypeKindEnum ? $"{unwrappedType.Name}?" : ScalarToNetType(baseType, argument.Name, unwrappedType);

            if (isNotNull)
            {
                argumentNetType = argumentNetType.TrimEnd('?');
            }

            if (unwrappedType.Kind == GraphQlTypeKindInputObject)
            {
                argumentNetType = $"{unwrappedType.Name}{GraphQlGeneratorConfiguration.ClassPostfix}";
            }

            var argumentDefinition = $"{argumentNetType} {argument.Name}";

            if (!isNotNull)
            {
                argumentDefinition = $"{argumentDefinition} = null";
            }

            return(argumentDefinition);
        }
Exemplo n.º 8
0
        private static string GetDataPropertyType(GraphQlType baseType, IGraphQlMember member)
        {
            string propertyType;
            var    fieldType = member.Type.UnwrapIfNonNull();

            switch (fieldType.Kind)
            {
            case GraphQlTypeKind.Object:
            case GraphQlTypeKind.Interface:
            case GraphQlTypeKind.Union:
            case GraphQlTypeKind.InputObject:
                var fieldTypeName = fieldType.Name;
                fieldTypeName = UseCustomClassNameIfDefined(fieldTypeName);
                propertyType  = $"{fieldTypeName}{GraphQlGeneratorConfiguration.ClassPostfix}";
                return(AddQuestionMarkIfNullableReferencesEnabled(propertyType));

            case GraphQlTypeKind.Enum:
                return(GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping(baseType, member.Type, member.Name));

            case GraphQlTypeKind.List:
                var itemTypeName = fieldType.OfType.UnwrapIfNonNull().Name;
                itemTypeName = UseCustomClassNameIfDefined(itemTypeName);
                var itemType         = IsUnknownObjectScalar(baseType, member.Name, fieldType.OfType) ? "object" : $"{itemTypeName}{GraphQlGeneratorConfiguration.ClassPostfix}";
                var suggestedNetType = ScalarToNetType(baseType, member.Name, fieldType.OfType).TrimEnd('?');
                if (!String.Equals(suggestedNetType, "object") && !String.Equals(suggestedNetType, "object?") && !suggestedNetType.TrimEnd().EndsWith("System.Object") && !suggestedNetType.TrimEnd().EndsWith("System.Object?"))
                {
                    itemType = suggestedNetType;
                }

                propertyType = $"ICollection<{itemType}>";

                return(AddQuestionMarkIfNullableReferencesEnabled(propertyType));

            case GraphQlTypeKind.Scalar:
                switch (fieldType.Name)
                {
                case GraphQlTypeBase.GraphQlTypeScalarInteger:
                    return(GetIntegerNetType(baseType, member.Type, member.Name));

                case GraphQlTypeBase.GraphQlTypeScalarString:
                    return(GetCustomScalarType(baseType, member.Type, member.Name));

                case GraphQlTypeBase.GraphQlTypeScalarFloat:
                    return(GetFloatNetType(baseType, member.Type, member.Name));

                case GraphQlTypeBase.GraphQlTypeScalarBoolean:
                    return(GetBooleanNetType(baseType, member.Type, member.Name));

                case GraphQlTypeBase.GraphQlTypeScalarId:
                    return(GetIdNetType(baseType, member.Type, member.Name));

                default:
                    return(GetCustomScalarType(baseType, member.Type, member.Name));
                }

            default:
                return(AddQuestionMarkIfNullableReferencesEnabled("string"));
            }
        }
Exemplo n.º 9
0
        public static string DefaultScalarFieldTypeMapping(GraphQlType baseType, GraphQlTypeBase valueType, string valueName)
        {
            valueName = NamingHelper.ToPascalCase(valueName);
            if (valueName == "From" || valueName == "ValidFrom" || valueName == "CreatedAt" ||
                valueName == "To" || valueName == "ValidTo" || valueName == "ModifiedAt" || valueName.EndsWith("Timestamp"))
            {
                return("DateTimeOffset?");
            }

            return(valueType.Name == GraphQlTypeBase.GraphQlTypeScalarString ? "string" : "object");
        }
Exemplo n.º 10
0
        private static void GenerateDataProperty(
            GraphQlType baseType,
            IGraphQlMember member,
            bool isInterfaceMember,
            bool isDeprecated,
            string deprecationReason,
            bool decorateWithJsonProperty,
            WriteDataClassPropertyBodyDelegate writeBody,
            StringBuilder builder)
        {
            var propertyName = NamingHelper.ToPascalCase(member.Name);

            var propertyType = GetDataPropertyType(baseType, member);

            GenerateCodeComments(builder, member.Description, 4);

            if (isDeprecated)
            {
                deprecationReason = String.IsNullOrWhiteSpace(deprecationReason) ? null : $"(@\"{deprecationReason.Replace("\"", "\"\"")}\")";
                builder.AppendLine($"    [Obsolete{deprecationReason}]");
            }

            if (decorateWithJsonProperty)
            {
                decorateWithJsonProperty =
                    GraphQlGeneratorConfiguration.JsonPropertyGeneration == JsonPropertyGenerationOption.Always ||
                    !String.Equals(
                        member.Name,
                        propertyName,
                        GraphQlGeneratorConfiguration.JsonPropertyGeneration == JsonPropertyGenerationOption.CaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);

                if (GraphQlGeneratorConfiguration.JsonPropertyGeneration == JsonPropertyGenerationOption.Never)
                {
                    decorateWithJsonProperty = false;
                }
            }

            if (!isInterfaceMember && decorateWithJsonProperty)
            {
                builder.AppendLine($"    [JsonProperty(\"{member.Name}\")]");
            }

            if (baseType.Kind == GraphQlTypeKind.InputObject)
            {
                builder.AppendLine($"    [JsonConverter(typeof(QueryBuilderParameterConverter<{propertyType}>))]");
                propertyType = AddQuestionMarkIfNullableReferencesEnabled($"QueryBuilderParameter<{propertyType}>");
            }

            builder.Append($"    {(isInterfaceMember ? null : "public ")}{propertyType} {propertyName}");

            writeBody(propertyType, GetBackingFieldName(member.Name));

            builder.AppendLine();
        }
        private static bool IsUnknownObjectScalar(GraphQlType baseType, string valueName, GraphQlFieldType fieldType)
        {
            fieldType = fieldType.UnwrapIfNonNull();

            if (fieldType.Kind != GraphQlTypeKindScalar)
            {
                return(false);
            }

            var netType = ScalarToNetType(baseType, valueName, fieldType);

            return(netType == "object" || netType.TrimEnd().EndsWith("System.Object"));
        }
Exemplo n.º 12
0
        public static string DefaultScalarFieldTypeMapping(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("DateTimeOffset?");
            }

            var dataType = valueType.Name == GraphQlTypeBase.GraphQlTypeScalarString ? "string" : "object";

            return(GraphQlGenerator.AddQuestionMarkIfNullableReferencesEnabled(dataType));
        }
        private static string GetIdNetType(GraphQlType baseType, GraphQlTypeBase valueType, string valueName)
        {
            switch (GraphQlGeneratorConfiguration.IdType)
            {
            case IdType.String: return("string");

            case IdType.Guid: return("Guid?");

            case IdType.Object: return("object");

            case IdType.Custom: return(GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping(baseType, valueType, valueName));

            default: throw new InvalidOperationException($"'{GraphQlGeneratorConfiguration.IdType}' not supported");
            }
        }
        private static string GetCustomScalarType(GraphQlType baseType, GraphQlTypeBase valueType, string valueName)
        {
            if (GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping == null)
            {
                throw new InvalidOperationException($"'{nameof(GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping)}' missing");
            }

            var netType = GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping(baseType, valueType, valueName);

            if (String.IsNullOrWhiteSpace(netType))
            {
                throw new InvalidOperationException($".NET type for '{baseType.Name}.{valueName}' ({valueType.Name}) cannot be resolved. Please check {nameof(GraphQlGeneratorConfiguration)}.{nameof(GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping)} implementation. ");
            }

            return(netType);
        }
Exemplo n.º 15
0
        private static IList <GraphQlField> GetFieldsToGenerate(GraphQlType type, IDictionary <string, GraphQlType> complexTypeDictionary)
        {
            var typeFields = type.Fields;

            if (type.Kind == GraphQlTypeKindUnion)
            {
                var unionFields     = new List <GraphQlField>();
                var unionFieldNames = new HashSet <string>();
                foreach (var possibleType in type.PossibleTypes)
                {
                    if (complexTypeDictionary.TryGetValue(possibleType.Name, out var consistOfType) && consistOfType.Fields != null)
                    {
                        unionFields.AddRange(consistOfType.Fields.Where(f => unionFieldNames.Add(f.Name)));
                    }
                }

                typeFields = unionFields;
            }

            return(typeFields?.Where(FilterDeprecatedFields).ToList());
        }
        private static string BuildMethodParameterDefinition(GraphQlType baseType, GraphQlArgument argument)
        {
            var isArgumentNotNull = argument.Type.Kind == GraphQlTypeKindNonNull;
            var isTypeNotNull     = isArgumentNotNull;
            var unwrappedType     = argument.Type.UnwrapIfNonNull();
            var isCollection      = unwrappedType.Kind == GraphQlTypeKindList;

            if (isCollection)
            {
                isTypeNotNull = unwrappedType.OfType.Kind == GraphQlTypeKindNonNull;
                unwrappedType = unwrappedType.OfType.UnwrapIfNonNull();
            }

            var argumentNetType = unwrappedType.Kind == GraphQlTypeKindEnum ? $"{unwrappedType.Name}?" : ScalarToNetType(baseType, argument.Name, unwrappedType);

            if (isTypeNotNull)
            {
                argumentNetType = argumentNetType.TrimEnd('?');
            }

            if (unwrappedType.Kind == GraphQlTypeKindInputObject)
            {
                argumentNetType = $"{unwrappedType.Name}{GraphQlGeneratorConfiguration.ClassPostfix}";
            }

            if (isCollection)
            {
                argumentNetType = $"IEnumerable<{argumentNetType}>";
            }

            var argumentDefinition = $"{argumentNetType} {NamingHelper.ToValidVariableName(argument.Name)}";

            if (!isArgumentNotNull)
            {
                argumentDefinition = $"{argumentDefinition} = null";
            }

            return(argumentDefinition);
        }
        private static void GenerateInputDataClassBody(GraphQlType type, StringBuilder builder)
        {
            foreach (var field in type.InputFields)
            {
                GenerateDataProperty(type, field, false, null, builder);
            }

            builder.AppendLine();
            builder.AppendLine("    protected override IEnumerable<InputPropertyInfo> GetPropertyValues()");
            builder.AppendLine("    {");

            foreach (var field in type.InputFields)
            {
                var propertyName = NamingHelper.ToPascalCase(field.Name);
                builder.Append("        yield return new InputPropertyInfo { Name = \"");
                builder.Append(field.Name);
                builder.Append("\", Value = ");
                builder.Append(propertyName);
                builder.AppendLine(" };");
            }

            builder.AppendLine("    }");
        }
        private static void GenerateInputDataClassBody(GraphQlType type, ICollection <IGraphQlMember> members, StringBuilder builder)
        {
            foreach (var member in members)
            {
                GenerateDataProperty(type, member, false, false, null, builder);
            }

            builder.AppendLine();
            builder.AppendLine("    IEnumerable<InputPropertyInfo> IGraphQlInputObject.GetPropertyValues()");
            builder.AppendLine("    {");

            foreach (var member in members)
            {
                var propertyName = NamingHelper.ToPascalCase(member.Name);
                builder.Append("        yield return new InputPropertyInfo { Name = \"");
                builder.Append(member.Name);
                builder.Append("\", Value = ");
                builder.Append(propertyName);
                builder.AppendLine(" };");
            }

            builder.AppendLine("    }");
        }
Exemplo n.º 19
0
        private static void GenerateEnum(GraphQlType type, StringBuilder builder)
        {
            builder.Append("public enum ");
            builder.AppendLine(type.Name);
            builder.AppendLine("{");

            var enumValues = type.EnumValues.ToList();

            for (var i = 0; i < enumValues.Count; i++)
            {
                var enumValue = enumValues[i];
                builder.Append($"    [EnumMember(Value=\"{enumValue.Name}\")] {NamingHelper.ToNetEnumName(enumValue.Name)}");

                if (i < enumValues.Count - 1)
                {
                    builder.Append(",");
                }

                builder.AppendLine();
            }

            builder.AppendLine("}");
        }
Exemplo n.º 20
0
 private static string GetBooleanNetType(GraphQlType baseType, GraphQlTypeBase valueType, string valueName) =>
 GraphQlGeneratorConfiguration.BooleanTypeMapping switch
 {
        private static void GenerateDataClass(GraphQlType type, StringBuilder builder)
        {
            var className = $"{type.Name}{GraphQlGeneratorConfiguration.ClassPostfix}";

            ValidateClassName(className);

            builder.Append("public class ");
            builder.AppendLine(className);
            builder.AppendLine("{");

            foreach (var field in type.Fields)
            {
                var propertyName = NamingHelper.CapitalizeFirst(field.Name);

                string propertyType;
                var    fieldType = UnwrapNonNull(field.Type);
                switch (fieldType.Kind)
                {
                case GraphQlTypeKindObject:
                    propertyType = $"{fieldType.Name}{GraphQlGeneratorConfiguration.ClassPostfix}";
                    break;

                case GraphQlTypeKindEnum:
                    propertyType = $"{fieldType.Name}?";
                    break;

                case GraphQlTypeKindList:
                    var itemType         = IsObjectScalar(fieldType.OfType) ? "object" : $"{UnwrapNonNull(fieldType.OfType).Name}{GraphQlGeneratorConfiguration.ClassPostfix}";
                    var suggestedNetType = ScalarToNetType(UnwrapNonNull(fieldType.OfType).Name).TrimEnd('?');
                    if (!String.Equals(suggestedNetType, "object"))
                    {
                        itemType = suggestedNetType;
                    }

                    propertyType = $"ICollection<{itemType}>";
                    break;

                case GraphQlTypeKindScalar:
                    switch (fieldType.Name)
                    {
                    case "Int":
                        propertyType = "int?";
                        break;

                    case "String":
                        propertyType = "string";
                        if (propertyName == "From" || propertyName == "ValidFrom" || propertyName == "CreatedAt" ||
                            propertyName == "To" || propertyName == "ValidTo" || propertyName == "ModifiedAt" || propertyName.EndsWith("Timestamp"))
                        {
                            propertyType = "DateTimeOffset?";
                        }

                        break;

                    case "Float":
                        propertyType = "decimal?";
                        break;

                    case "Boolean":
                        propertyType = "bool?";
                        break;

                    case "ID":
                        propertyType = "Guid?";
                        break;

                    default:
                        propertyType = "object";
                        break;
                    }

                    break;

                default:
                    propertyType = "string";
                    break;
                }

                builder.AppendLine($"    public {propertyType} {propertyName} {{ get; set; }}");
            }

            builder.Append("}");
        }
        private static void GenerateTypeQueryBuilder(GraphQlType type, string queryPrefix, StringBuilder builder)
        {
            var className = $"{type.Name}QueryBuilder{GraphQlGeneratorConfiguration.ClassPostfix}";

            ValidateClassName(className);

            builder.AppendLine($"public {(GraphQlGeneratorConfiguration.GeneratePartialClasses ? "partial " : null)}class {className} : GraphQlQueryBuilder<{className}>");
            builder.AppendLine("{");

            builder.AppendLine("    private static readonly FieldMetadata[] AllFieldMetadata =");
            builder.AppendLine("        new []");
            builder.AppendLine("        {");

            var fields = type.Fields?.ToArray();

            for (var i = 0; i < fields?.Length; i++)
            {
                var comma     = i == fields.Length - 1 ? null : ",";
                var field     = fields[i];
                var fieldType = field.Type.UnwrapIfNonNull();
                var isList    = fieldType.Kind == GraphQlTypeKindList;
                var treatUnknownObjectAsComplex = IsUnknownObjectScalar(type, field.Name, fieldType) && !GraphQlGeneratorConfiguration.TreatUnknownObjectAsScalar;
                var isComplex = isList || treatUnknownObjectAsComplex || IsComplexType(fieldType.Kind);

                builder.Append($"            new FieldMetadata {{ Name = \"{field.Name}\"");

                if (isComplex)
                {
                    builder.Append(", IsComplex = true");

                    fieldType = isList ? fieldType.OfType.UnwrapIfNonNull() : fieldType;

                    if (fieldType.Kind != GraphQlTypeKindScalar && fieldType.Kind != GraphQlTypeKindEnum)
                    {
                        builder.Append($", QueryBuilderType = typeof({fieldType.Name}QueryBuilder{GraphQlGeneratorConfiguration.ClassPostfix})");
                    }
                }

                builder.AppendLine($" }}{comma}");
            }

            builder.AppendLine("        };");
            builder.AppendLine();

            if (!String.IsNullOrEmpty(queryPrefix))
            {
                WriteOverrideProperty("string", "Prefix", $"\"{queryPrefix}\"", builder);
            }

            WriteOverrideProperty("IList<FieldMetadata>", "AllFields", "AllFieldMetadata", builder);

            for (var i = 0; i < fields?.Length; i++)
            {
                var field     = fields[i];
                var fieldType = field.Type.UnwrapIfNonNull();
                if (fieldType.Kind == GraphQlTypeKindList)
                {
                    fieldType = fieldType.OfType;
                }
                fieldType = fieldType.UnwrapIfNonNull();

                bool IsCompatibleArgument(GraphQlFieldType argumentType)
                {
                    argumentType = argumentType.UnwrapIfNonNull();
                    switch (argumentType.Kind)
                    {
                    case GraphQlTypeKindScalar:
                    case GraphQlTypeKindEnum:
                    case GraphQlTypeKindInputObject:
                        return(true);

                    case GraphQlTypeKindList:
                        return(IsCompatibleArgument(argumentType.OfType));

                    default:
                        return(false);
                    }
                }

                var args             = field.Args?.Where(a => IsCompatibleArgument(a.Type)).ToArray() ?? new GraphQlArgument[0];
                var methodParameters =
                    String.Join(
                        ", ",
                        args
                        .OrderByDescending(a => a.Type.Kind == GraphQlTypeKindNonNull)
                        .Select(a => BuildMethodParameterDefinition(type, a)));

                var requiresFullBody = GraphQlGeneratorConfiguration.CSharpVersion == CSharpVersion.Compatible || args.Any();
                var returnPrefix     = requiresFullBody ? "        return " : String.Empty;

                if (fieldType.Kind == GraphQlTypeKindScalar || fieldType.Kind == GraphQlTypeKindEnum || fieldType.Kind == GraphQlTypeKindScalar)
                {
                    builder.Append($"    public {className} With{NamingHelper.ToPascalCase(field.Name)}({methodParameters})");

                    if (requiresFullBody)
                    {
                        builder.AppendLine();
                        builder.AppendLine("    {");
                        AppendArgumentDictionary(builder, args);
                    }
                    else
                    {
                        builder.Append(" => ");
                    }

                    builder.Append($"{returnPrefix}WithScalarField(\"{field.Name}\"");

                    if (args.Length > 0)
                    {
                        builder.Append(", args");
                    }

                    builder.AppendLine(");");

                    if (requiresFullBody)
                    {
                        builder.AppendLine("    }");
                    }
                }
                else
                {
                    if (String.IsNullOrEmpty(fieldType.Name))
                    {
                        throw new InvalidOperationException($"Field '{field.Name}' type name not resolved. ");
                    }

                    var builderParameterName = NamingHelper.LowerFirst(fieldType.Name);
                    builder.Append($"    public {className} With{NamingHelper.ToPascalCase(field.Name)}({fieldType.Name}QueryBuilder{GraphQlGeneratorConfiguration.ClassPostfix} {builderParameterName}QueryBuilder");

                    if (args.Length > 0)
                    {
                        builder.Append(", ");
                        builder.Append(methodParameters);
                    }

                    builder.Append(")");

                    if (requiresFullBody)
                    {
                        builder.AppendLine();
                        builder.AppendLine("    {");
                    }
                    else
                    {
                        builder.Append(" => ");
                    }

                    AppendArgumentDictionary(builder, args);

                    builder.Append($"{returnPrefix}WithObjectField(\"{field.Name}\", {builderParameterName}QueryBuilder");

                    if (args.Length > 0)
                    {
                        builder.Append(", args");
                    }

                    builder.AppendLine(");");

                    if (requiresFullBody)
                    {
                        builder.AppendLine("    }");
                    }
                }

                if (i < fields.Length - 1)
                {
                    builder.AppendLine();
                }
            }

            builder.AppendLine("}");
        }
        private static void GenerateTypeQueryBuilder(GraphQlType type, StringBuilder builder)
        {
            var className = $"{type.Name}QueryBuilder{GraphQlGeneratorConfiguration.ClassPostfix}";

            ValidateClassName(className);

            builder.AppendLine($"public class {className} : GraphQlQueryBuilder<{className}>");
            builder.AppendLine("{");

            var fields = type.Fields.ToArray();

            builder.AppendLine("    protected override IList<FieldMetadata> AllFields { get; } =");
            builder.AppendLine("        new []");
            builder.AppendLine("        {");

            for (var i = 0; i < fields.Length; i++)
            {
                var comma     = i == fields.Length - 1 ? null : ",";
                var field     = fields[i];
                var fieldType = UnwrapNonNull(field.Type);
                var isList    = fieldType.Kind == GraphQlTypeKindList;
                var isComplex = isList || IsObjectScalar(fieldType) || fieldType.Kind == GraphQlTypeKindObject;

                builder.Append($"            new FieldMetadata {{ Name = \"{field.Name}\"");

                if (isComplex)
                {
                    builder.Append(", IsComplex = true");

                    fieldType = isList ? UnwrapNonNull(fieldType.OfType) : fieldType;
                    if (fieldType.Kind != GraphQlTypeKindScalar)
                    {
                        builder.Append($", QueryBuilderType = typeof({fieldType.Name}QueryBuilder{GraphQlGeneratorConfiguration.ClassPostfix})");
                    }
                }

                builder.AppendLine($" }}{comma}");
            }

            builder.AppendLine("        };");
            builder.AppendLine();

            for (var i = 0; i < fields.Length; i++)
            {
                var field     = fields[i];
                var fieldType = UnwrapNonNull(field.Type);
                if (fieldType.Kind == GraphQlTypeKindList)
                {
                    fieldType = fieldType.OfType;
                }
                fieldType = UnwrapNonNull(fieldType);

                var args             = field.Args?.Where(a => UnwrapNonNull(a.Type).Kind == GraphQlTypeKindScalar || UnwrapNonNull(a.Type).Kind == GraphQlTypeKindEnum).ToArray() ?? new GraphQlArgument[0];
                var methodParameters = String.Join(", ", args.Select(a => $"{(UnwrapNonNull(a.Type).Kind == GraphQlTypeKindEnum ? $"{UnwrapNonNull(a.Type).Name}?" : ScalarToNetType(UnwrapNonNull(a.Type).Name))} {a.Name} = null"));
                var requiresFullBody = GraphQlGeneratorConfiguration.CSharpVersion == CSharpVersion.Compatible || args.Any();
                var returnPrefix     = requiresFullBody ? "        return " :  String.Empty;

                if (fieldType.Kind == GraphQlTypeKindScalar || fieldType.Kind == GraphQlTypeKindEnum || fieldType.Kind == GraphQlTypeKindScalar)
                {
                    builder.Append($"    public {className} With{NamingHelper.CapitalizeFirst(field.Name)}({methodParameters})");

                    if (requiresFullBody)
                    {
                        builder.AppendLine();
                        builder.AppendLine("    {");
                        AppendArgumentDictionary(builder, args);
                    }
                    else
                    {
                        builder.Append(" => ");
                    }

                    builder.Append($"{returnPrefix}WithScalarField(\"{field.Name}\"");

                    if (args.Length > 0)
                    {
                        builder.Append(", args");
                    }

                    builder.AppendLine(");");

                    if (requiresFullBody)
                    {
                        builder.AppendLine("    }");
                    }
                }
                else
                {
                    if (String.IsNullOrEmpty(fieldType.Name))
                    {
                        throw new InvalidOperationException($"Field '{field.Name}' type name not resolved. ");
                    }

                    var builderParameterName = NamingHelper.LowerFirst(fieldType.Name);
                    builder.Append($"    public {className} With{NamingHelper.CapitalizeFirst(field.Name)}({fieldType.Name}QueryBuilder{GraphQlGeneratorConfiguration.ClassPostfix} {builderParameterName}QueryBuilder");

                    if (args.Length > 0)
                    {
                        builder.Append(", ");
                        builder.Append(methodParameters);
                    }

                    builder.Append(")");

                    if (requiresFullBody)
                    {
                        builder.AppendLine();
                        builder.AppendLine("    {");
                    }
                    else
                    {
                        builder.Append(" => ");
                    }

                    AppendArgumentDictionary(builder, args);

                    builder.Append($"{returnPrefix}WithObjectField(\"{field.Name}\", {builderParameterName}QueryBuilder");

                    if (args.Length > 0)
                    {
                        builder.Append(", args");
                    }

                    builder.AppendLine(");");

                    if (requiresFullBody)
                    {
                        builder.AppendLine("    }");
                    }
                }

                if (i < fields.Length - 1)
                {
                    builder.AppendLine();
                }
            }

            builder.AppendLine("}");
        }
        private static void GenerateDataProperty(GraphQlType baseType, IGraphQlMember member, bool isInterfaceMember, bool isDeprecated, string deprecationReason, StringBuilder builder)
        {
            var propertyName = NamingHelper.ToPascalCase(member.Name);

            string propertyType;
            var    fieldType = member.Type.UnwrapIfNonNull();

            switch (fieldType.Kind)
            {
            case GraphQlTypeKindObject:
            case GraphQlTypeKindInterface:
            case GraphQlTypeKindUnion:
            case GraphQlTypeKindInputObject:
                propertyType = $"{fieldType.Name}{GraphQlGeneratorConfiguration.ClassPostfix}";
                break;

            case GraphQlTypeKindEnum:
                propertyType = $"{fieldType.Name}?";
                break;

            case GraphQlTypeKindList:
                var itemType         = IsUnknownObjectScalar(baseType, member.Name, fieldType.OfType) ? "object" : $"{fieldType.OfType.UnwrapIfNonNull().Name}{GraphQlGeneratorConfiguration.ClassPostfix}";
                var suggestedNetType = ScalarToNetType(baseType, member.Name, fieldType.OfType.UnwrapIfNonNull()).TrimEnd('?');
                if (!String.Equals(suggestedNetType, "object") && !suggestedNetType.TrimEnd().EndsWith("System.Object"))
                {
                    itemType = suggestedNetType;
                }

                propertyType = $"ICollection<{itemType}>";
                break;

            case GraphQlTypeKindScalar:
                switch (fieldType.Name)
                {
                case GraphQlTypeBase.GraphQlTypeScalarInteger:
                    propertyType = GetIntegerNetType();
                    break;

                case GraphQlTypeBase.GraphQlTypeScalarString:
                    propertyType = GetCustomScalarType(baseType, fieldType, member.Name);
                    break;

                case GraphQlTypeBase.GraphQlTypeScalarFloat:
                    propertyType = GetFloatNetType();
                    break;

                case GraphQlTypeBase.GraphQlTypeScalarBoolean:
                    propertyType = "bool?";
                    break;

                case GraphQlTypeBase.GraphQlTypeScalarId:
                    propertyType = GetIdNetType(baseType, fieldType, member.Name);
                    break;

                default:
                    propertyType = GetCustomScalarType(baseType, fieldType, member.Name);
                    break;
                }

                break;

            default:
                propertyType = "string";
                break;
            }

            GenerateCodeComments(builder, member.Description);

            if (isDeprecated)
            {
                deprecationReason = String.IsNullOrWhiteSpace(deprecationReason) ? null : $"(@\"{deprecationReason.Replace("\"", "\"\"")}\")";
                builder.AppendLine($"    [Obsolete{deprecationReason}]");
            }

            builder.AppendLine($"    {(isInterfaceMember ? null : "public ")}{propertyType} {propertyName} {{ get; set; }}");
        }
Exemplo n.º 25
0
        private static void GenerateInputDataClassBody(GraphQlType type, IEnumerable <IGraphQlMember> members, StringBuilder builder)
        {
            var fieldNameMembers = new Dictionary <string, IGraphQlMember>();

            foreach (var member in members)
            {
                var propertyName = NamingHelper.ToPascalCase(member.Name);
                var fieldName    = "_" + Char.ToLower(propertyName[0]) + propertyName.Substring(1);
                fieldNameMembers.Add(fieldName, member);

                builder.Append("    private InputPropertyInfo ");
                builder.Append(fieldName);
                builder.AppendLine(";");
            }

            builder.AppendLine();

            var useCompatibleSyntax = GraphQlGeneratorConfiguration.CSharpVersion == CSharpVersion.Compatible;

            foreach (var kvp in fieldNameMembers)
            {
                GenerateDataProperty(
                    type,
                    kvp.Value,
                    false,
                    false,
                    null,
                    false,
                    t =>
                {
                    builder.AppendLine();
                    builder.AppendLine("    {");
                    builder.Append("        get");
                    builder.Append(useCompatibleSyntax ? " { return " : " => ");
                    builder.Append("(");
                    builder.Append(t);
                    builder.Append(")");
                    builder.Append(kvp.Key);
                    builder.Append(".Value;");

                    if (useCompatibleSyntax)
                    {
                        builder.Append(" }");
                    }

                    builder.AppendLine();

                    builder.Append("        set");
                    builder.Append(useCompatibleSyntax ? " { " : " => ");
                    builder.Append(kvp.Key);
                    builder.Append(" = new InputPropertyInfo { Name = \"");
                    builder.Append(kvp.Value.Name);
                    builder.Append("\", Value = value };");

                    if (useCompatibleSyntax)
                    {
                        builder.Append(" }");
                    }

                    builder.AppendLine();
                    builder.AppendLine("    }");
                },
                    builder);
            }

            builder.AppendLine("    IEnumerable<InputPropertyInfo> IGraphQlInputObject.GetPropertyValues()");
            builder.AppendLine("    {");

            foreach (var fieldName in fieldNameMembers.Keys)
            {
                builder.Append("        if (");
                builder.Append(fieldName);
                builder.Append(".Name != null) yield return ");
                builder.Append(fieldName);
                builder.AppendLine(";");
            }

            builder.AppendLine("    }");
        }
Exemplo n.º 26
0
        private static void GenerateDataProperty(
            GraphQlType baseType,
            IGraphQlMember member,
            bool isInterfaceMember,
            bool isDeprecated,
            string deprecationReason,
            bool decorateWithJsonProperty,
            WriteDataClassPropertyBodyDelegate writeBody,
            StringBuilder builder)
        {
            var propertyName = NamingHelper.ToPascalCase(member.Name);

            string propertyType;
            var    fieldType = member.Type.UnwrapIfNonNull();

            switch (fieldType.Kind)
            {
            case GraphQlTypeKindObject:
            case GraphQlTypeKindInterface:
            case GraphQlTypeKindUnion:
            case GraphQlTypeKindInputObject:
                var fieldTypeName = fieldType.Name;
                fieldTypeName = UseCustomClassNameIfDefined(fieldTypeName);
                propertyType  = $"{fieldTypeName}{GraphQlGeneratorConfiguration.ClassPostfix}";
                propertyType  = AddQuestionMarkIfNullableReferencesEnabled(propertyType);
                break;

            case GraphQlTypeKindEnum:
                propertyType = $"{fieldType.Name}?";
                break;

            case GraphQlTypeKindList:
                var itemTypeName = fieldType.OfType.UnwrapIfNonNull().Name;
                itemTypeName = UseCustomClassNameIfDefined(itemTypeName);
                var itemType         = IsUnknownObjectScalar(baseType, member.Name, fieldType.OfType) ? "object" : $"{itemTypeName}{GraphQlGeneratorConfiguration.ClassPostfix}";
                var suggestedNetType = ScalarToNetType(baseType, member.Name, fieldType.OfType.UnwrapIfNonNull()).TrimEnd('?');
                if (!String.Equals(suggestedNetType, "object") && !String.Equals(suggestedNetType, "object?") && !suggestedNetType.TrimEnd().EndsWith("System.Object") && !suggestedNetType.TrimEnd().EndsWith("System.Object?"))
                {
                    itemType = suggestedNetType;
                }

                propertyType = $"ICollection<{itemType}>";

                propertyType = AddQuestionMarkIfNullableReferencesEnabled(propertyType);

                break;

            case GraphQlTypeKindScalar:
                switch (fieldType.Name)
                {
                case GraphQlTypeBase.GraphQlTypeScalarInteger:
                    propertyType = GetIntegerNetType();
                    break;

                case GraphQlTypeBase.GraphQlTypeScalarString:
                    propertyType = GetCustomScalarType(baseType, fieldType, member.Name);
                    break;

                case GraphQlTypeBase.GraphQlTypeScalarFloat:
                    propertyType = GetFloatNetType();
                    break;

                case GraphQlTypeBase.GraphQlTypeScalarBoolean:
                    propertyType = "bool?";
                    break;

                case GraphQlTypeBase.GraphQlTypeScalarId:
                    propertyType = GetIdNetType(baseType, fieldType, member.Name);
                    break;

                default:
                    propertyType = GetCustomScalarType(baseType, fieldType, member.Name);
                    break;
                }

                break;

            default:
                propertyType = AddQuestionMarkIfNullableReferencesEnabled("string");
                break;
            }

            GenerateCodeComments(builder, member.Description, 4);

            if (isDeprecated)
            {
                deprecationReason = String.IsNullOrWhiteSpace(deprecationReason) ? null : $"(@\"{deprecationReason.Replace("\"", "\"\"")}\")";
                builder.AppendLine($"    [Obsolete{deprecationReason}]");
            }

            if (decorateWithJsonProperty)
            {
                decorateWithJsonProperty =
                    GraphQlGeneratorConfiguration.JsonPropertyGeneration == JsonPropertyGenerationOption.Always ||
                    !String.Equals(
                        member.Name,
                        propertyName,
                        GraphQlGeneratorConfiguration.JsonPropertyGeneration == JsonPropertyGenerationOption.CaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);

                if (GraphQlGeneratorConfiguration.JsonPropertyGeneration == JsonPropertyGenerationOption.Never)
                {
                    decorateWithJsonProperty = false;
                }
            }

            if (!isInterfaceMember && decorateWithJsonProperty)
            {
                builder.AppendLine($"    [JsonProperty(\"{member.Name}\")]");
            }

            builder.Append($"    {(isInterfaceMember ? null : "public ")}{propertyType} {propertyName}");

            writeBody(propertyType);

            builder.AppendLine();
        }
        private static void GenerateDataProperty(GraphQlType baseType, IGraphQlMember member, bool isDeprecated, string deprecationReason, StringBuilder builder)
        {
            var propertyName = NamingHelper.ToPascalCase(member.Name);

            string propertyType;
            var    fieldType = UnwrapNonNull(member.Type);

            switch (fieldType.Kind)
            {
            case GraphQlTypeKindObject:
                propertyType = $"{fieldType.Name}{GraphQlGeneratorConfiguration.ClassPostfix}";
                break;

            case GraphQlTypeKindEnum:
                propertyType = $"{fieldType.Name}?";
                break;

            case GraphQlTypeKindList:
                var itemType         = IsObjectScalar(fieldType.OfType) ? "object" : $"{UnwrapNonNull(fieldType.OfType).Name}{GraphQlGeneratorConfiguration.ClassPostfix}";
                var suggestedNetType = ScalarToNetType(baseType, member.Name, UnwrapNonNull(fieldType.OfType)).TrimEnd('?');
                if (!String.Equals(suggestedNetType, "object"))
                {
                    itemType = suggestedNetType;
                }

                propertyType = $"ICollection<{itemType}>";
                break;

            case GraphQlTypeKindScalar:
                switch (fieldType.Name)
                {
                case "Int":
                    propertyType = "int?";
                    break;

                case "Byte":
                    propertyType = "byte?";
                    break;

                case "String":
                    propertyType = GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping(baseType, fieldType, member.Name);
                    break;

                case "Float":
                    propertyType = "decimal?";
                    break;

                case "Boolean":
                    propertyType = "bool?";
                    break;

                case "ID":
                    propertyType = "Guid?";
                    break;

                case "DateTime":
                    propertyType = "DateTime?";
                    break;

                default:
                    propertyType = GraphQlGeneratorConfiguration.CustomScalarFieldTypeMapping(baseType, fieldType, member.Name);
                    break;
                }

                break;

            default:
                propertyType = "string";
                break;
            }

            GenerateCodeComments(builder, member.Description);

            if (isDeprecated)
            {
                deprecationReason = String.IsNullOrWhiteSpace(deprecationReason) ? null : $"(@\"{deprecationReason.Replace("\"", "\"\"")}\")";
                builder.AppendLine($"    [Obsolete{deprecationReason}]");
            }

            builder.AppendLine($"    public {propertyType} {propertyName} {{ get; set; }}");
        }
Exemplo n.º 28
0
        public static void GenerateDataClass(GraphQlType type, StringBuilder builder)
        {
            var className = $"{type.Name}{GraphQlGeneratorConfiguration.ClassPostfix}";

            ValidateClassName(className);

            builder.Append("public class ");
            builder.AppendLine(className);
            builder.AppendLine("{");

            foreach (var field in type.Fields)
            {
                var propertyName = NamingHelper.CapitalizeFirst(field.Name);

                string propertyType;
                var    fieldType = UnwrapNonNull(field.Type);
                switch (fieldType.Kind)
                {
                case GraphQlTypeKindObject:
                    propertyType = $"{fieldType.Name}{GraphQlGeneratorConfiguration.ClassPostfix}";
                    break;

                case GraphQlTypeKindEnum:
                    propertyType = $"{fieldType.Name}?";
                    break;

                case GraphQlTypeKindList:
                    var itemType         = IsObjectScalar(fieldType.OfType) ? "object" : $"{UnwrapNonNull(fieldType.OfType).Name}{GraphQlGeneratorConfiguration.ClassPostfix}";
                    var suggestedNetType = ScalarToNetType(UnwrapNonNull(fieldType.OfType).Name).TrimEnd('?');
                    if (!String.Equals(suggestedNetType, "object"))
                    {
                        itemType = suggestedNetType;
                    }

                    propertyType = $"ICollection<{itemType}>";
                    break;

                case GraphQlTypeKindScalar:
                    switch (fieldType.Name)
                    {
                    case "Int":
                        propertyType = "int?";
                        break;

                    case "String":
                        propertyType = GraphQlGeneratorConfiguration.CustomScalarFieldMapping(field);
                        break;

                    case "Float":
                        propertyType = "decimal?";
                        break;

                    case "Boolean":
                        propertyType = "bool?";
                        break;

                    case "ID":
                        propertyType = "Guid?";
                        break;

                    default:
                        propertyType = "object";
                        break;
                    }

                    break;

                default:
                    propertyType = "string";
                    break;
                }

                if (GraphQlGeneratorConfiguration.GenerateComments && !String.IsNullOrWhiteSpace(field.Description))
                {
                    builder.AppendLine("    /// <summary>");
                    builder.AppendLine($"    /// {field.Description}");
                    builder.AppendLine("    /// </summary>");
                }

                builder.AppendLine($"    public {propertyType} {propertyName} {{ get; set; }}");
            }

            builder.Append("}");
        }