lib/graphql/schema/build_from_definition.rb in graphql-1.11.4 vs lib/graphql/schema/build_from_definition.rb in graphql-1.11.5
- old
+ new
@@ -2,23 +2,30 @@
require "graphql/schema/build_from_definition/resolve_map"
module GraphQL
class Schema
module BuildFromDefinition
+ if !String.method_defined?(:-@)
+ using GraphQL::StringDedupBackport
+ end
+
class << self
# @see {Schema.from_definition}
- def from_definition(definition_string, default_resolve:, using: {}, relay: false, interpreter: true, parser: DefaultParser)
- document = parser.parse(definition_string)
- default_resolve ||= {}
- Builder.build(document, default_resolve: default_resolve, relay: relay, using: using, interpreter: interpreter)
+ def from_definition(definition_string, parser: GraphQL.default_parser, **kwargs)
+ from_document(parser.parse(definition_string), **kwargs)
end
+
+ def from_definition_path(definition_path, parser: GraphQL.default_parser, **kwargs)
+ from_document(parser.parse_file(definition_path), **kwargs)
+ end
+
+ def from_document(document, default_resolve:, using: {}, relay: false, interpreter: true)
+ Builder.build(document, default_resolve: default_resolve || {}, relay: relay, using: using, interpreter: interpreter)
+ end
end
# @api private
- DefaultParser = GraphQL::Language::Parser
-
- # @api private
module Builder
extend self
def build(document, default_resolve:, using: {}, interpreter: true, relay:)
raise InvalidDocumentError.new('Must provide a document ast.') if !document || !document.is_a?(GraphQL::Language::Nodes::Document)
@@ -41,11 +48,11 @@
when GraphQL::Language::Nodes::SchemaDefinition
nil # already handled
when GraphQL::Language::Nodes::EnumTypeDefinition
types[definition.name] = build_enum_type(definition, type_resolver)
when GraphQL::Language::Nodes::ObjectTypeDefinition
- types[definition.name] = build_object_type(definition, type_resolver, default_resolve: default_resolve)
+ types[definition.name] = build_object_type(definition, type_resolver)
when GraphQL::Language::Nodes::InterfaceTypeDefinition
types[definition.name] = build_interface_type(definition, type_resolver)
when GraphQL::Language::Nodes::UnionTypeDefinition
types[definition.name] = build_union_type(definition, type_resolver)
when GraphQL::Language::Nodes::ScalarTypeDefinition
@@ -109,15 +116,15 @@
err_backtrace = err.backtrace
raise InvalidDocumentError, "Type \"#{type_name}\" not found in document.", err_backtrace
end
if default_resolve.respond_to?(:resolve_type)
- define_singleton_method(:resolve_type) do |*args|
- default_resolve.resolve_type(*args)
+ def self.resolve_type(*args)
+ self.definition_default_resolve.resolve_type(*args)
end
else
- define_singleton_method(:resolve_type) do |*args|
+ def self.resolve_type(*args)
NullResolveType.call(*args)
end
end
directives directives.values
@@ -139,10 +146,24 @@
end
end
# Empty `orphan_types` -- this will make unreachable types ... unreachable.
own_orphan_types.clear
+
+ class << self
+ attr_accessor :definition_default_resolve
+ end
+
+ self.definition_default_resolve = default_resolve
+
+ def definition_default_resolve
+ self.class.definition_default_resolve
+ end
+
+ def self.inherited(child_class)
+ child_class.definition_default_resolve = self.definition_default_resolve
+ end
end
end
NullResolveType = ->(type, obj, ctx) {
raise(GraphQL::RequiredImplementationMissingError, "Generated Schema cannot use Interface or Union types for execution. Implement resolve_type on your resolver.")
@@ -180,16 +201,16 @@
graphql_name(scalar_type_definition.name)
description(scalar_type_definition.description)
ast_node(scalar_type_definition)
if default_resolve.respond_to?(:coerce_input)
- define_singleton_method(:coerce_input) do |val, ctx|
- default_resolve.coerce_input(self, val, ctx)
+ def self.coerce_input(val, ctx)
+ ctx.schema.definition_default_resolve.coerce_input(self, val, ctx)
end
- define_singleton_method(:coerce_result) do |val, ctx|
- default_resolve.coerce_result(self, val, ctx)
+ def self.coerce_result(val, ctx)
+ ctx.schema.definition_default_resolve.coerce_result(self, val, ctx)
end
end
end
end
@@ -200,27 +221,24 @@
possible_types(*union_type_definition.types.map { |type_name| type_resolver.call(type_name) })
ast_node(union_type_definition)
end
end
- def build_object_type(object_type_definition, type_resolver, default_resolve:)
+ def build_object_type(object_type_definition, type_resolver)
builder = self
- type_def = nil
- typed_resolve_fn = ->(field, obj, args, ctx) { default_resolve.call(type_def, field, obj, args, ctx) }
Class.new(GraphQL::Schema::Object) do
- type_def = self
graphql_name(object_type_definition.name)
description(object_type_definition.description)
ast_node(object_type_definition)
object_type_definition.interfaces.each do |interface_name|
interface_defn = type_resolver.call(interface_name)
implements(interface_defn)
end
- builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve: typed_resolve_fn)
+ builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve: true)
end
end
def build_input_object_type(input_object_type_definition, type_resolver)
builder = self
@@ -245,24 +263,28 @@
else
default_value
end
end
+ NO_DEFAULT_VALUE = {}.freeze
+
def build_arguments(type_class, arguments, type_resolver)
builder = self
arguments.each do |argument_defn|
- default_value_kwargs = {}
- if !argument_defn.default_value.nil?
- default_value_kwargs[:default_value] = builder.build_default_value(argument_defn.default_value)
+ default_value_kwargs = if !argument_defn.default_value.nil?
+ { default_value: builder.build_default_value(argument_defn.default_value) }
+ else
+ NO_DEFAULT_VALUE
end
type_class.argument(
argument_defn.name,
type: type_resolver.call(argument_defn.type),
required: false,
description: argument_defn.description,
+ deprecation_reason: builder.build_deprecation_reason(argument_defn.directives),
ast_node: argument_defn,
camelize: false,
method_access: false,
**default_value_kwargs
)
@@ -293,14 +315,14 @@
end
def build_fields(owner, field_definitions, type_resolver, default_resolve:)
builder = self
- field_definitions.map do |field_definition|
+ field_definitions.each do |field_definition|
type_name = resolve_type_name(field_definition.type)
- resolve_method_name = "resolve_field_#{field_definition.name}"
- owner.field(
+ resolve_method_name = -"resolve_field_#{field_definition.name}"
+ schema_field_defn = owner.field(
field_definition.name,
description: field_definition.description,
type: type_resolver.call(field_definition.type),
null: true,
connection: type_name.end_with?("Connection"),
@@ -308,19 +330,22 @@
deprecation_reason: build_deprecation_reason(field_definition.directives),
ast_node: field_definition,
method_conflict_warning: false,
camelize: false,
resolver_method: resolve_method_name,
- ) do
- builder.build_arguments(self, field_definition.arguments, type_resolver)
+ )
- # Don't do this for interfaces
- if default_resolve
- owner.send(:define_method, resolve_method_name) do |**args|
- field_instance = self.class.get_field(field_definition.name)
- default_resolve.call(field_instance, object, args, context)
+ builder.build_arguments(schema_field_defn, field_definition.arguments, type_resolver)
+
+ # Don't do this for interfaces
+ if default_resolve
+ owner.class_eval <<-RUBY, __FILE__, __LINE__
+ # frozen_string_literal: true
+ def #{resolve_method_name}(**args)
+ field_instance = self.class.get_field("#{field_definition.name}")
+ context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
end
- end
+ RUBY
end
end
end
def resolve_type(types, ast_node)