class WCC::Contentful::Graphql::Federation::NamespacesTypes

This GraphQL type definition wraps a type definition from an external schema and redefines it in our top-level schema, so that names do not clash. ex. “Campus” in the events schema becomes “Event_Campus”

Attributes

namespace[R]

Public Class Methods

new(namespace:) click to toggle source
# File lib/wcc/contentful/graphql/federation/namespaces_types.rb, line 15
def initialize(namespace:)
  @namespace = namespace
end
registry() click to toggle source
# File lib/wcc/contentful/graphql/federation/namespaces_types.rb, line 8
def registry
  @registry ||= {}
end

Public Instance Methods

namespaced(type) click to toggle source

Gets the graphql type definition for the externally resolved field

# File lib/wcc/contentful/graphql/federation/namespaces_types.rb, line 20
def namespaced(type)
  return type if type.default_scalar?
  return namespaced(type.of_type).to_list_type if type.is_a?(GraphQL::ListType)
  return namespaced(type.of_type).to_non_null_type if type.is_a?(GraphQL::NonNullType)

  me = self
  ns = namespace
  typename = [namespace, type.to_s].compact.join('_')
  self.class.registry[typename] ||=
    if type.is_a?(GraphQL::UnionType)
      possible_types =
        type.possible_types.map { |t| me.namespaced(t) }
      GraphQL::UnionType.define do
        name typename
        possible_types possible_types
      end
    elsif type.is_a?(GraphQL::InputObjectType)
      GraphQL::InputObjectType.define do
        name typename
        type.arguments.each do |(name, arg)|
          argument name, me.namespaced(arg.type)
        end
      end
    elsif type.is_a?(GraphQL::ScalarType)
      GraphQL::ScalarType.define do
        name typename

        coerce_input type.method(:coerce_input)
        coerce_result type.method(:coerce_result)
      end
    elsif type.is_a?(GraphQL::ObjectType)
      GraphQL::ObjectType.define do
        name typename
        description "#{type.name} from remote#{ns ? ' ' + ns : ''}"

        type.fields.each do |(name, field_def)|
          field name, me.namespaced(field_def.type) do
            field_def.arguments.each do |(arg_name, arg)|
              argument arg_name, me.namespaced(arg.type)
            end

            resolve ->(obj, _args, _ctx) do
              # The object is a JSON response that came back from the
              # external schema.  Resolve the value by using the hash key.
              obj[name]
            end
          end
        end
      end
    else
      raise ArgumentError, "Cannot namespace type #{type} (#{type.class})"
    end
end