Skip to content

Commit c03731e

Browse files
authored
Merge pull request #2618 from joeytepp/fix-nilable-scalar-types
Fix nullability of GraphQL scalar types when passed as required arguments
2 parents dbcf83d + 57bdcab commit c03731e

2 files changed

Lines changed: 42 additions & 1 deletion

File tree

lib/tapioca/dsl/helpers/graphql_type_helper.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ def type_for(type, ignore_nilable_wrapper: false, prepare_method: nil)
8080
signature = Runtime::Reflection.signature_of(method)
8181
return_type = signature&.return_type
8282

83-
valid_return_type?(return_type) ? return_type.to_s : "T.untyped"
83+
# Wrap as non-nilable for required arguments. `coerce_input` supports both
84+
# required and optional; optional arguments are re-wrapped below based on `type.non_null?`
85+
valid_return_type?(return_type) ? RBIHelper.as_non_nilable_type(return_type.to_s) : "T.untyped"
8486
when GraphQL::Schema::InputObject.singleton_class
8587
type_for_constant(unwrapped_type)
8688
when Module

spec/tapioca/dsl/compilers/graphql_mutation_spec.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,45 @@ def resolve(loaded_argument:, loaded_arguments:, custom_name:, optional_loaded_a
361361
assert_equal(expected, rbi_for(:CreateComment))
362362
end
363363

364+
it "generates correct RBI for custom scalars whose coerce_input returns a nilable type" do
365+
add_ruby_file("create_comment.rb", <<~RUBY)
366+
class CustomScalar; end
367+
368+
class NilableScalarType < GraphQL::Schema::Scalar
369+
class << self
370+
extend T::Sig
371+
372+
sig { params(value: T.untyped, context: GraphQL::Query::Context).returns(T.nilable(CustomScalar)) }
373+
def coerce_input(value, context)
374+
return nil if value.nil?
375+
CustomScalar.new
376+
end
377+
end
378+
end
379+
380+
class CreateComment < GraphQL::Schema::Mutation
381+
argument :required_scalar, NilableScalarType, required: true
382+
argument :required_scalar_array, [NilableScalarType], required: true
383+
argument :optional_scalar, NilableScalarType, required: false
384+
385+
def resolve(required_scalar:, required_scalar_array:, optional_scalar: nil)
386+
# ...
387+
end
388+
end
389+
RUBY
390+
391+
expected = <<~RBI
392+
# typed: strong
393+
394+
class CreateComment
395+
sig { params(required_scalar: ::CustomScalar, required_scalar_array: T::Array[::CustomScalar], optional_scalar: T.nilable(::CustomScalar)).returns(T.untyped) }
396+
def resolve(required_scalar:, required_scalar_array:, optional_scalar: T.unsafe(nil)); end
397+
end
398+
RBI
399+
400+
assert_equal(expected, rbi_for(:CreateComment))
401+
end
402+
364403
it "generates correct RBI for custom scalars with return types" do
365404
add_ruby_file("create_comment.rb", <<~RUBY)
366405
class CustomScalar; end

0 commit comments

Comments
 (0)