# typed: strict # frozen_string_literal: true module Tapioca module Dsl module Helpers module GraphqlTypeHelper extend self extend T::Sig sig { params(argument: GraphQL::Schema::Argument).returns(String) } def type_for(argument) type = if argument.loads loads_type = ::GraphQL::Schema::Wrapper.new(argument.loads) loads_type = loads_type.to_list_type if argument.type.list? loads_type = loads_type.to_non_null_type if argument.type.non_null? loads_type else argument.type end unwrapped_type = type.unwrap parsed_type = case unwrapped_type when GraphQL::Types::Boolean.singleton_class "T::Boolean" when GraphQL::Types::Float.singleton_class type_for_constant(Float) when GraphQL::Types::ID.singleton_class, GraphQL::Types::String.singleton_class type_for_constant(String) when GraphQL::Types::Int.singleton_class, GraphQL::Types::BigInt.singleton_class type_for_constant(Integer) when GraphQL::Types::ISO8601Date.singleton_class type_for_constant(Date) when GraphQL::Types::ISO8601DateTime.singleton_class type_for_constant(Time) when GraphQL::Types::JSON.singleton_class "T::Hash[::String, T.untyped]" when GraphQL::Schema::Enum.singleton_class enum_values = T.cast(unwrapped_type.enum_values, T::Array[GraphQL::Schema::EnumValue]) value_types = enum_values.map { |v| type_for_constant(v.value.class) }.uniq if value_types.size == 1 T.must(value_types.first) else "T.any(#{value_types.join(", ")})" end when GraphQL::Schema::Scalar.singleton_class method = Runtime::Reflection.method_of(unwrapped_type, :coerce_input) signature = Runtime::Reflection.signature_of(method) return_type = signature&.return_type if return_type && !(T::Private::Types::Void === return_type || T::Private::Types::NotTyped === return_type) return_type.to_s else "T.untyped" end when GraphQL::Schema::InputObject.singleton_class type_for_constant(unwrapped_type) when Module Runtime::Reflection.qualified_name_of(unwrapped_type) || "T.untyped" else "T.untyped" end if type.list? parsed_type = "T::Array[#{parsed_type}]" end unless type.non_null? || has_replaceable_default?(argument) parsed_type = RBIHelper.as_nilable_type(parsed_type) end parsed_type end private sig { params(constant: Module).returns(String) } def type_for_constant(constant) Runtime::Reflection.qualified_name_of(constant) || "T.untyped" end sig { params(argument: GraphQL::Schema::Argument).returns(T::Boolean) } def has_replaceable_default?(argument) !!argument.replace_null_with_default? && !argument.default_value.nil? end end end end end