Class: RuboCop::Cop::GraphQL::DisallowedTypes

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/graphql/disallowed_types.rb

Overview

Flags field and argument types the project has decided not to expose, with a message explaining what to use instead.

Every schema accumulates types that are still resolvable but shouldn't be reached for in new code: a scalar kept alive only for backwards compatibility, a type that predates a better one, or a builtin whose semantics don't fit the domain -- Float for money, say, where the serialization loses precision. The convention is usually documented and then re-litigated in review; this makes it fail the build instead.

Nothing is disallowed by default: the cop is inert until Types is configured.

A configured name matches the written constant exactly, or as a trailing segment of it, so Float covers Float, Types::Float and GraphQL::Types::Float. Configure GraphQL::Types::Float instead to match only the fully qualified form.

List types are unwrapped, so [Float] and [Float, null: true] are flagged too, and both the positional type and the type: keyword are checked.

Examples:

Types: => 'Use Types::Decimal, which serializes as a string.'

# bad
field :amount, Float, null: false
argument :amount, Float, required: true
field :amounts, [Float], null: false
field :amount, type: Float, null: false

# good
field :amount, Types::Decimal, null: false
argument :amount, Types::Decimal, required: true

Types: => 'Use GraphQL::Types::ISO8601Date.'

# bad
field :starts_on, Types::LegacyDate, null: false

# good
field :starts_on, GraphQL::Types::ISO8601Date, null: false

Constant Summary collapse

MSG =
"`%<type>s` is not allowed as a field or argument type."
MSG_WITH_REASON =
"`%<type>s` is not allowed as a field or argument type. %<reason>s"
RESTRICT_ON_SEND =
%i[field argument].freeze

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rubocop/cop/graphql/disallowed_types.rb', line 48

def on_send(node)
  return if disallowed_types.empty?
  return unless type_declaration?(node)

  each_type_const(node) do |const_node|
    configured_name = disallowed_name_for(const_node)
    next unless configured_name

    add_offense(const_node, message: message_for(configured_name))
  end
end