graphql 1.9.17 → 1.11.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +18 -2
- data/lib/generators/graphql/install_generator.rb +27 -0
- data/lib/generators/graphql/object_generator.rb +52 -8
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_mutation.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/enum.erb +2 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +14 -10
- data/lib/generators/graphql/templates/interface.erb +2 -0
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +2 -0
- data/lib/generators/graphql/templates/mutation_type.erb +2 -0
- data/lib/generators/graphql/templates/object.erb +2 -0
- data/lib/generators/graphql/templates/query_type.erb +2 -0
- data/lib/generators/graphql/templates/scalar.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +10 -0
- data/lib/generators/graphql/templates/union.erb +3 -1
- data/lib/graphql/analysis/ast/field_usage.rb +1 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +178 -67
- data/lib/graphql/analysis/ast/visitor.rb +3 -3
- data/lib/graphql/analysis/ast.rb +12 -11
- data/lib/graphql/argument.rb +10 -38
- data/lib/graphql/backtrace/table.rb +10 -2
- data/lib/graphql/backtrace/tracer.rb +2 -1
- data/lib/graphql/base_type.rb +4 -0
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +2 -2
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +5 -9
- data/lib/graphql/define/assign_enum_value.rb +1 -1
- data/lib/graphql/define/assign_global_id_field.rb +2 -2
- data/lib/graphql/define/assign_object_field.rb +3 -3
- data/lib/graphql/define/defined_object_proxy.rb +3 -0
- data/lib/graphql/define/instance_definable.rb +18 -108
- data/lib/graphql/directive/deprecated_directive.rb +1 -12
- data/lib/graphql/directive.rb +8 -1
- data/lib/graphql/enum_type.rb +5 -71
- data/lib/graphql/execution/directive_checks.rb +2 -2
- data/lib/graphql/execution/errors.rb +2 -3
- data/lib/graphql/execution/execute.rb +1 -1
- data/lib/graphql/execution/instrumentation.rb +1 -1
- data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
- data/lib/graphql/execution/interpreter/arguments.rb +51 -0
- data/lib/graphql/execution/interpreter/arguments_cache.rb +79 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +25 -0
- data/lib/graphql/execution/interpreter/runtime.rb +227 -254
- data/lib/graphql/execution/interpreter.rb +34 -11
- data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
- data/lib/graphql/execution/lookahead.rb +39 -114
- data/lib/graphql/execution/multiplex.rb +14 -5
- data/lib/graphql/field.rb +14 -118
- data/lib/graphql/filter.rb +1 -1
- data/lib/graphql/function.rb +1 -30
- data/lib/graphql/input_object_type.rb +6 -24
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/interface_type.rb +7 -23
- data/lib/graphql/internal_representation/scope.rb +2 -2
- data/lib/graphql/internal_representation/visit.rb +2 -2
- data/lib/graphql/introspection/base_object.rb +2 -5
- data/lib/graphql/introspection/directive_type.rb +1 -1
- data/lib/graphql/introspection/entry_points.rb +7 -7
- data/lib/graphql/introspection/field_type.rb +7 -3
- data/lib/graphql/introspection/input_value_type.rb +33 -9
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +4 -9
- data/lib/graphql/introspection/type_type.rb +11 -7
- data/lib/graphql/introspection.rb +96 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +24 -5
- data/lib/graphql/language/definition_slice.rb +21 -10
- data/lib/graphql/language/document_from_schema_definition.rb +89 -64
- data/lib/graphql/language/lexer.rb +7 -3
- data/lib/graphql/language/lexer.rl +7 -3
- data/lib/graphql/language/nodes.rb +52 -91
- data/lib/graphql/language/parser.rb +719 -717
- data/lib/graphql/language/parser.y +104 -98
- data/lib/graphql/language/printer.rb +1 -1
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/visitor.rb +2 -2
- data/lib/graphql/language.rb +2 -1
- data/lib/graphql/name_validator.rb +6 -7
- data/lib/graphql/non_null_type.rb +0 -10
- data/lib/graphql/object_type.rb +45 -56
- data/lib/graphql/pagination/active_record_relation_connection.rb +41 -0
- data/lib/graphql/pagination/array_connection.rb +77 -0
- data/lib/graphql/pagination/connection.rb +208 -0
- data/lib/graphql/pagination/connections.rb +145 -0
- data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
- data/lib/graphql/pagination/relation_connection.rb +185 -0
- data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
- data/lib/graphql/pagination.rb +6 -0
- data/lib/graphql/query/arguments.rb +4 -2
- data/lib/graphql/query/context.rb +36 -9
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +23 -6
- data/lib/graphql/query/literal_input.rb +30 -10
- data/lib/graphql/query/null_context.rb +5 -1
- data/lib/graphql/query/validation_pipeline.rb +4 -1
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query/variables.rb +16 -7
- data/lib/graphql/query.rb +64 -15
- data/lib/graphql/rake_task/validate.rb +3 -0
- data/lib/graphql/rake_task.rb +9 -9
- data/lib/graphql/relay/array_connection.rb +10 -12
- data/lib/graphql/relay/base_connection.rb +23 -13
- data/lib/graphql/relay/connection_type.rb +2 -1
- data/lib/graphql/relay/edge_type.rb +1 -0
- data/lib/graphql/relay/edges_instrumentation.rb +1 -1
- data/lib/graphql/relay/mutation.rb +1 -86
- data/lib/graphql/relay/node.rb +2 -2
- data/lib/graphql/relay/range_add.rb +14 -5
- data/lib/graphql/relay/relation_connection.rb +8 -10
- data/lib/graphql/scalar_type.rb +15 -59
- data/lib/graphql/schema/argument.rb +113 -11
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
- data/lib/graphql/schema/build_from_definition.rb +212 -190
- data/lib/graphql/schema/built_in_types.rb +5 -5
- data/lib/graphql/schema/default_type_error.rb +2 -0
- data/lib/graphql/schema/directive/deprecated.rb +18 -0
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive.rb +34 -3
- data/lib/graphql/schema/enum.rb +52 -4
- data/lib/graphql/schema/enum_value.rb +6 -1
- data/lib/graphql/schema/field/connection_extension.rb +44 -20
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +200 -129
- data/lib/graphql/schema/find_inherited_value.rb +13 -0
- data/lib/graphql/schema/finder.rb +13 -11
- data/lib/graphql/schema/input_object.rb +131 -22
- data/lib/graphql/schema/interface.rb +26 -8
- data/lib/graphql/schema/introspection_system.rb +108 -37
- data/lib/graphql/schema/late_bound_type.rb +3 -2
- data/lib/graphql/schema/list.rb +47 -0
- data/lib/graphql/schema/loader.rb +134 -96
- data/lib/graphql/schema/member/base_dsl_methods.rb +29 -12
- data/lib/graphql/schema/member/build_type.rb +19 -5
- data/lib/graphql/schema/member/cached_graphql_definition.rb +5 -0
- data/lib/graphql/schema/member/has_arguments.rb +105 -5
- data/lib/graphql/schema/member/has_ast_node.rb +20 -0
- data/lib/graphql/schema/member/has_fields.rb +20 -10
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +2 -2
- data/lib/graphql/schema/member/validates_input.rb +33 -0
- data/lib/graphql/schema/member.rb +6 -0
- data/lib/graphql/schema/mutation.rb +5 -1
- data/lib/graphql/schema/non_null.rb +30 -0
- data/lib/graphql/schema/object.rb +65 -12
- data/lib/graphql/schema/possible_types.rb +9 -4
- data/lib/graphql/schema/printer.rb +0 -15
- data/lib/graphql/schema/relay_classic_mutation.rb +5 -3
- data/lib/graphql/schema/resolver/has_payload_type.rb +5 -2
- data/lib/graphql/schema/resolver.rb +26 -18
- data/lib/graphql/schema/scalar.rb +27 -3
- data/lib/graphql/schema/subscription.rb +8 -18
- data/lib/graphql/schema/timeout.rb +29 -15
- data/lib/graphql/schema/traversal.rb +1 -1
- data/lib/graphql/schema/type_expression.rb +21 -13
- data/lib/graphql/schema/type_membership.rb +2 -2
- data/lib/graphql/schema/union.rb +37 -3
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validation.rb +10 -2
- data/lib/graphql/schema/warden.rb +115 -29
- data/lib/graphql/schema.rb +903 -195
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/base_visitor.rb +10 -6
- data/lib/graphql/static_validation/literal_validator.rb +52 -27
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +43 -83
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +17 -5
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +33 -25
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +29 -21
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +2 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -5
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +5 -6
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
- data/lib/graphql/static_validation/type_stack.rb +2 -2
- data/lib/graphql/static_validation/validation_context.rb +1 -1
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +30 -8
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +89 -19
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +84 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +21 -0
- data/lib/graphql/subscriptions/event.rb +23 -5
- data/lib/graphql/subscriptions/instrumentation.rb +10 -5
- data/lib/graphql/subscriptions/serialize.rb +22 -4
- data/lib/graphql/subscriptions/subscription_root.rb +15 -5
- data/lib/graphql/subscriptions.rb +108 -35
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +14 -10
- data/lib/graphql/tracing/appoptics_tracing.rb +171 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +8 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +8 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
- data/lib/graphql/tracing/platform_tracing.rb +53 -9
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
- data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
- data/lib/graphql/tracing/scout_tracing.rb +19 -0
- data/lib/graphql/tracing/skylight_tracing.rb +8 -0
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +14 -34
- data/lib/graphql/types/big_int.rb +1 -1
- data/lib/graphql/types/int.rb +9 -2
- data/lib/graphql/types/iso_8601_date.rb +3 -3
- data/lib/graphql/types/iso_8601_date_time.rb +25 -10
- data/lib/graphql/types/relay/base_connection.rb +11 -7
- data/lib/graphql/types/relay/base_edge.rb +2 -1
- data/lib/graphql/types/string.rb +7 -1
- data/lib/graphql/unauthorized_error.rb +1 -1
- data/lib/graphql/union_type.rb +13 -28
- data/lib/graphql/unresolved_type_error.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +31 -6
- data/readme.md +1 -1
- metadata +34 -9
- data/lib/graphql/literal_validation_error.rb +0 -6
@@ -4,24 +4,22 @@ require "graphql/schema/build_from_definition/resolve_map"
|
|
4
4
|
module GraphQL
|
5
5
|
class Schema
|
6
6
|
module BuildFromDefinition
|
7
|
+
if !String.method_defined?(:-@)
|
8
|
+
using GraphQL::StringDedupBackport
|
9
|
+
end
|
10
|
+
|
7
11
|
class << self
|
8
|
-
|
9
|
-
|
10
|
-
|
12
|
+
# @see {Schema.from_definition}
|
13
|
+
def from_definition(definition_string, parser: GraphQL.default_parser, **kwargs)
|
14
|
+
from_document(parser.parse(definition_string), **kwargs)
|
11
15
|
end
|
12
|
-
end
|
13
16
|
|
14
|
-
|
15
|
-
|
17
|
+
def from_definition_path(definition_path, parser: GraphQL.default_parser, **kwargs)
|
18
|
+
from_document(parser.parse_file(definition_path), **kwargs)
|
19
|
+
end
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
def self.call(type, field, obj, args, ctx)
|
20
|
-
if field.arguments.any?
|
21
|
-
obj.public_send(field.name, args, ctx)
|
22
|
-
else
|
23
|
-
obj.public_send(field.name)
|
24
|
-
end
|
21
|
+
def from_document(document, default_resolve:, using: {}, relay: false, interpreter: true)
|
22
|
+
Builder.build(document, default_resolve: default_resolve || {}, relay: relay, using: using, interpreter: interpreter)
|
25
23
|
end
|
26
24
|
end
|
27
25
|
|
@@ -29,28 +27,30 @@ module GraphQL
|
|
29
27
|
module Builder
|
30
28
|
extend self
|
31
29
|
|
32
|
-
def build(document, default_resolve:
|
30
|
+
def build(document, default_resolve:, using: {}, interpreter: true, relay:)
|
33
31
|
raise InvalidDocumentError.new('Must provide a document ast.') if !document || !document.is_a?(GraphQL::Language::Nodes::Document)
|
34
32
|
|
35
33
|
if default_resolve.is_a?(Hash)
|
36
34
|
default_resolve = ResolveMap.new(default_resolve)
|
37
35
|
end
|
38
36
|
|
39
|
-
|
37
|
+
schema_defns = document.definitions.select { |d| d.is_a?(GraphQL::Language::Nodes::SchemaDefinition) }
|
38
|
+
if schema_defns.size > 1
|
39
|
+
raise InvalidDocumentError.new('Must provide only one schema definition.')
|
40
|
+
end
|
41
|
+
schema_definition = schema_defns.first
|
40
42
|
types = {}
|
41
|
-
types.merge!(GraphQL::Schema::BUILT_IN_TYPES)
|
42
43
|
directives = {}
|
43
|
-
type_resolver = ->(type) {
|
44
|
+
type_resolver = ->(type) { resolve_type(types, type) }
|
44
45
|
|
45
46
|
document.definitions.each do |definition|
|
46
47
|
case definition
|
47
48
|
when GraphQL::Language::Nodes::SchemaDefinition
|
48
|
-
|
49
|
-
schema_definition = definition
|
49
|
+
nil # already handled
|
50
50
|
when GraphQL::Language::Nodes::EnumTypeDefinition
|
51
51
|
types[definition.name] = build_enum_type(definition, type_resolver)
|
52
52
|
when GraphQL::Language::Nodes::ObjectTypeDefinition
|
53
|
-
types[definition.name] = build_object_type(definition, type_resolver
|
53
|
+
types[definition.name] = build_object_type(definition, type_resolver)
|
54
54
|
when GraphQL::Language::Nodes::InterfaceTypeDefinition
|
55
55
|
types[definition.name] = build_interface_type(definition, type_resolver)
|
56
56
|
when GraphQL::Language::Nodes::UnionTypeDefinition
|
@@ -64,6 +64,21 @@ module GraphQL
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
+
# At this point, if types named by the built in types are _late-bound_ types,
|
68
|
+
# that means they were referenced in the schema but not defined in the schema.
|
69
|
+
# That's supported for built-in types. (Eg, you can use `String` without defining it.)
|
70
|
+
# In that case, insert the concrete type definition now.
|
71
|
+
#
|
72
|
+
# However, if the type in `types` is a _concrete_ type definition, that means that
|
73
|
+
# the document contained an explicit definition of the scalar type.
|
74
|
+
# Don't override it in this case.
|
75
|
+
GraphQL::Schema::BUILT_IN_TYPES.each do |scalar_name, built_in_scalar|
|
76
|
+
existing_type = types[scalar_name]
|
77
|
+
if existing_type.is_a?(GraphQL::Schema::LateBoundType)
|
78
|
+
types[scalar_name] = built_in_scalar
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
67
82
|
directives = GraphQL::Schema.default_directives.merge(directives)
|
68
83
|
|
69
84
|
if schema_definition
|
@@ -89,54 +104,86 @@ module GraphQL
|
|
89
104
|
|
90
105
|
raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
|
91
106
|
|
92
|
-
|
93
|
-
|
107
|
+
Class.new(GraphQL::Schema) do
|
108
|
+
begin
|
109
|
+
# Add these first so that there's some chance of resolving late-bound types
|
110
|
+
orphan_types types.values
|
111
|
+
query query_root_type
|
112
|
+
mutation mutation_root_type
|
113
|
+
subscription subscription_root_type
|
114
|
+
rescue Schema::UnresolvedLateBoundTypeError => err
|
115
|
+
type_name = err.type.name
|
116
|
+
err_backtrace = err.backtrace
|
117
|
+
raise InvalidDocumentError, "Type \"#{type_name}\" not found in document.", err_backtrace
|
118
|
+
end
|
94
119
|
|
95
|
-
query query_root_type
|
96
|
-
mutation mutation_root_type
|
97
|
-
subscription subscription_root_type
|
98
|
-
orphan_types types.values
|
99
120
|
if default_resolve.respond_to?(:resolve_type)
|
100
|
-
resolve_type(
|
121
|
+
def self.resolve_type(*args)
|
122
|
+
self.definition_default_resolve.resolve_type(*args)
|
123
|
+
end
|
101
124
|
else
|
102
|
-
resolve_type(
|
125
|
+
def self.resolve_type(*args)
|
126
|
+
NullResolveType.call(*args)
|
127
|
+
end
|
103
128
|
end
|
104
129
|
|
105
130
|
directives directives.values
|
106
|
-
end
|
107
131
|
|
108
|
-
|
132
|
+
if schema_definition
|
133
|
+
ast_node(schema_definition)
|
134
|
+
end
|
135
|
+
|
136
|
+
if interpreter
|
137
|
+
use GraphQL::Execution::Interpreter
|
138
|
+
use GraphQL::Analysis::AST
|
139
|
+
end
|
140
|
+
|
141
|
+
using.each do |plugin, options|
|
142
|
+
if options
|
143
|
+
use(plugin, **options)
|
144
|
+
else
|
145
|
+
use(plugin)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Empty `orphan_types` -- this will make unreachable types ... unreachable.
|
150
|
+
own_orphan_types.clear
|
151
|
+
|
152
|
+
class << self
|
153
|
+
attr_accessor :definition_default_resolve
|
154
|
+
end
|
109
155
|
|
110
|
-
|
156
|
+
self.definition_default_resolve = default_resolve
|
157
|
+
|
158
|
+
def definition_default_resolve
|
159
|
+
self.class.definition_default_resolve
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.inherited(child_class)
|
163
|
+
child_class.definition_default_resolve = self.definition_default_resolve
|
164
|
+
end
|
165
|
+
end
|
111
166
|
end
|
112
167
|
|
113
168
|
NullResolveType = ->(type, obj, ctx) {
|
114
169
|
raise(GraphQL::RequiredImplementationMissingError, "Generated Schema cannot use Interface or Union types for execution. Implement resolve_type on your resolver.")
|
115
170
|
}
|
116
171
|
|
117
|
-
NullScalarCoerce = ->(val, _ctx) { val }
|
118
|
-
|
119
172
|
def build_enum_type(enum_type_definition, type_resolver)
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
173
|
+
builder = self
|
174
|
+
Class.new(GraphQL::Schema::Enum) do
|
175
|
+
graphql_name(enum_type_definition.name)
|
176
|
+
description(enum_type_definition.description)
|
177
|
+
ast_node(enum_type_definition)
|
178
|
+
enum_type_definition.values.each do |enum_value_definition|
|
179
|
+
value(enum_value_definition.name,
|
126
180
|
value: enum_value_definition.name,
|
127
|
-
deprecation_reason: build_deprecation_reason(enum_value_definition.directives),
|
181
|
+
deprecation_reason: builder.build_deprecation_reason(enum_value_definition.directives),
|
128
182
|
description: enum_value_definition.description,
|
183
|
+
ast_node: enum_value_definition,
|
129
184
|
)
|
130
|
-
|
131
|
-
value.ast_node = enum_value_definition
|
132
|
-
|
133
|
-
value
|
134
185
|
end
|
135
|
-
|
136
|
-
|
137
|
-
enum.ast_node = enum_type_definition
|
138
|
-
|
139
|
-
enum
|
186
|
+
end
|
140
187
|
end
|
141
188
|
|
142
189
|
def build_deprecation_reason(directives)
|
@@ -144,65 +191,67 @@ module GraphQL
|
|
144
191
|
return unless deprecated_directive
|
145
192
|
|
146
193
|
reason = deprecated_directive.arguments.find{ |a| a.name == 'reason' }
|
147
|
-
return GraphQL::Directive::DEFAULT_DEPRECATION_REASON unless reason
|
194
|
+
return GraphQL::Schema::Directive::DEFAULT_DEPRECATION_REASON unless reason
|
148
195
|
|
149
196
|
reason.value
|
150
197
|
end
|
151
198
|
|
152
199
|
def build_scalar_type(scalar_type_definition, type_resolver, default_resolve:)
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
)
|
200
|
+
builder = self
|
201
|
+
Class.new(GraphQL::Schema::Scalar) do
|
202
|
+
graphql_name(scalar_type_definition.name)
|
203
|
+
description(scalar_type_definition.description)
|
204
|
+
ast_node(scalar_type_definition)
|
205
|
+
|
206
|
+
if default_resolve.respond_to?(:coerce_input)
|
207
|
+
# Put these method definitions in another method to avoid retaining `type_resolve`
|
208
|
+
# from this method's bindiing
|
209
|
+
builder.build_scalar_type_coerce_method(self, :coerce_input, default_resolve)
|
210
|
+
builder.build_scalar_type_coerce_method(self, :coerce_result, default_resolve)
|
211
|
+
end
|
166
212
|
end
|
213
|
+
end
|
167
214
|
|
168
|
-
|
215
|
+
def build_scalar_type_coerce_method(scalar_class, method_name, default_definition_resolve)
|
216
|
+
scalar_class.define_singleton_method(method_name) do |val, ctx|
|
217
|
+
default_definition_resolve.public_send(method_name, self, val, ctx)
|
218
|
+
end
|
169
219
|
end
|
170
220
|
|
171
221
|
def build_union_type(union_type_definition, type_resolver)
|
172
|
-
|
173
|
-
|
174
|
-
description
|
175
|
-
possible_types
|
176
|
-
|
222
|
+
Class.new(GraphQL::Schema::Union) do
|
223
|
+
graphql_name(union_type_definition.name)
|
224
|
+
description(union_type_definition.description)
|
225
|
+
possible_types(*union_type_definition.types.map { |type_name| type_resolver.call(type_name) })
|
226
|
+
ast_node(union_type_definition)
|
227
|
+
end
|
228
|
+
end
|
177
229
|
|
178
|
-
|
230
|
+
def build_object_type(object_type_definition, type_resolver)
|
231
|
+
builder = self
|
179
232
|
|
180
|
-
|
181
|
-
|
233
|
+
Class.new(GraphQL::Schema::Object) do
|
234
|
+
graphql_name(object_type_definition.name)
|
235
|
+
description(object_type_definition.description)
|
236
|
+
ast_node(object_type_definition)
|
237
|
+
|
238
|
+
object_type_definition.interfaces.each do |interface_name|
|
239
|
+
interface_defn = type_resolver.call(interface_name)
|
240
|
+
implements(interface_defn)
|
241
|
+
end
|
182
242
|
|
183
|
-
|
184
|
-
|
185
|
-
typed_resolve_fn = ->(field, obj, args, ctx) { default_resolve.call(type_def, field, obj, args, ctx) }
|
186
|
-
type_def = GraphQL::ObjectType.define(
|
187
|
-
name: object_type_definition.name,
|
188
|
-
description: object_type_definition.description,
|
189
|
-
fields: Hash[build_fields(object_type_definition.fields, type_resolver, default_resolve: typed_resolve_fn)],
|
190
|
-
interfaces: object_type_definition.interfaces.map{ |interface_name| type_resolver.call(interface_name) },
|
191
|
-
)
|
192
|
-
type_def.ast_node = object_type_definition
|
193
|
-
type_def
|
243
|
+
builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve: true)
|
244
|
+
end
|
194
245
|
end
|
195
246
|
|
196
247
|
def build_input_object_type(input_object_type_definition, type_resolver)
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
input
|
248
|
+
builder = self
|
249
|
+
Class.new(GraphQL::Schema::InputObject) do
|
250
|
+
graphql_name(input_object_type_definition.name)
|
251
|
+
description(input_object_type_definition.description)
|
252
|
+
ast_node(input_object_type_definition)
|
253
|
+
builder.build_arguments(self, input_object_type_definition.fields, type_resolver)
|
254
|
+
end
|
206
255
|
end
|
207
256
|
|
208
257
|
def build_default_value(default_value)
|
@@ -220,129 +269,102 @@ module GraphQL
|
|
220
269
|
end
|
221
270
|
end
|
222
271
|
|
223
|
-
|
224
|
-
|
225
|
-
|
272
|
+
NO_DEFAULT_VALUE = {}.freeze
|
273
|
+
|
274
|
+
def build_arguments(type_class, arguments, type_resolver)
|
275
|
+
builder = self
|
226
276
|
|
227
|
-
|
228
|
-
|
277
|
+
arguments.each do |argument_defn|
|
278
|
+
default_value_kwargs = if !argument_defn.default_value.nil?
|
279
|
+
{ default_value: builder.build_default_value(argument_defn.default_value) }
|
280
|
+
else
|
281
|
+
NO_DEFAULT_VALUE
|
229
282
|
end
|
230
283
|
|
231
|
-
argument
|
232
|
-
|
233
|
-
type: type_resolver.call(
|
234
|
-
|
284
|
+
type_class.argument(
|
285
|
+
argument_defn.name,
|
286
|
+
type: type_resolver.call(argument_defn.type),
|
287
|
+
required: false,
|
288
|
+
description: argument_defn.description,
|
289
|
+
deprecation_reason: builder.build_deprecation_reason(argument_defn.directives),
|
290
|
+
ast_node: argument_defn,
|
291
|
+
camelize: false,
|
235
292
|
method_access: false,
|
236
|
-
**
|
293
|
+
**default_value_kwargs
|
237
294
|
)
|
238
|
-
|
239
|
-
argument.ast_node = input_argument
|
240
|
-
|
241
|
-
[
|
242
|
-
input_argument.name,
|
243
|
-
argument
|
244
|
-
]
|
245
295
|
end
|
246
296
|
end
|
247
297
|
|
248
298
|
def build_directive(directive_definition, type_resolver)
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
locations
|
254
|
-
|
255
|
-
|
256
|
-
directive.ast_node = directive_definition
|
257
|
-
|
258
|
-
directive
|
259
|
-
end
|
260
|
-
|
261
|
-
def build_directive_arguments(directive_definition, type_resolver)
|
262
|
-
directive_definition.arguments.map do |directive_argument|
|
263
|
-
kwargs = {}
|
264
|
-
|
265
|
-
if !directive_argument.default_value.nil?
|
266
|
-
kwargs[:default_value] = build_default_value(directive_argument.default_value)
|
267
|
-
end
|
268
|
-
|
269
|
-
argument = GraphQL::Argument.define(
|
270
|
-
name: directive_argument.name,
|
271
|
-
type: type_resolver.call(directive_argument.type),
|
272
|
-
description: directive_argument.description,
|
273
|
-
method_access: false,
|
274
|
-
**kwargs,
|
275
|
-
)
|
276
|
-
|
277
|
-
argument.ast_node = directive_argument
|
278
|
-
|
279
|
-
[
|
280
|
-
directive_argument.name,
|
281
|
-
argument
|
282
|
-
]
|
299
|
+
builder = self
|
300
|
+
Class.new(GraphQL::Schema::Directive) do
|
301
|
+
graphql_name(directive_definition.name)
|
302
|
+
description(directive_definition.description)
|
303
|
+
locations(*directive_definition.locations.map { |location| location.name.to_sym })
|
304
|
+
ast_node(directive_definition)
|
305
|
+
builder.build_arguments(self, directive_definition.arguments, type_resolver)
|
283
306
|
end
|
284
307
|
end
|
285
308
|
|
286
309
|
def build_interface_type(interface_type_definition, type_resolver)
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
310
|
+
builder = self
|
311
|
+
Module.new do
|
312
|
+
include GraphQL::Schema::Interface
|
313
|
+
graphql_name(interface_type_definition.name)
|
314
|
+
description(interface_type_definition.description)
|
315
|
+
ast_node(interface_type_definition)
|
316
|
+
|
317
|
+
builder.build_fields(self, interface_type_definition.fields, type_resolver, default_resolve: nil)
|
318
|
+
end
|
296
319
|
end
|
297
320
|
|
298
|
-
def build_fields(field_definitions, type_resolver, default_resolve:)
|
299
|
-
|
300
|
-
field_arguments = Hash[field_definition.arguments.map do |argument|
|
301
|
-
kwargs = {}
|
302
|
-
|
303
|
-
if !argument.default_value.nil?
|
304
|
-
kwargs[:default_value] = build_default_value(argument.default_value)
|
305
|
-
end
|
306
|
-
|
307
|
-
arg = GraphQL::Argument.define(
|
308
|
-
name: argument.name,
|
309
|
-
description: argument.description,
|
310
|
-
type: type_resolver.call(argument.type),
|
311
|
-
method_access: false,
|
312
|
-
**kwargs,
|
313
|
-
)
|
314
|
-
|
315
|
-
arg.ast_node = argument
|
316
|
-
|
317
|
-
[argument.name, arg]
|
318
|
-
end]
|
321
|
+
def build_fields(owner, field_definitions, type_resolver, default_resolve:)
|
322
|
+
builder = self
|
319
323
|
|
320
|
-
|
321
|
-
|
324
|
+
field_definitions.each do |field_definition|
|
325
|
+
type_name = resolve_type_name(field_definition.type)
|
326
|
+
resolve_method_name = -"resolve_field_#{field_definition.name}"
|
327
|
+
schema_field_defn = owner.field(
|
328
|
+
field_definition.name,
|
322
329
|
description: field_definition.description,
|
323
330
|
type: type_resolver.call(field_definition.type),
|
324
|
-
|
325
|
-
|
331
|
+
null: true,
|
332
|
+
connection: type_name.end_with?("Connection"),
|
333
|
+
connection_extension: nil,
|
326
334
|
deprecation_reason: build_deprecation_reason(field_definition.directives),
|
335
|
+
ast_node: field_definition,
|
336
|
+
method_conflict_warning: false,
|
337
|
+
camelize: false,
|
338
|
+
resolver_method: resolve_method_name,
|
327
339
|
)
|
328
340
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
341
|
+
builder.build_arguments(schema_field_defn, field_definition.arguments, type_resolver)
|
342
|
+
|
343
|
+
# Don't do this for interfaces
|
344
|
+
if default_resolve
|
345
|
+
owner.class_eval <<-RUBY, __FILE__, __LINE__
|
346
|
+
# frozen_string_literal: true
|
347
|
+
def #{resolve_method_name}(**args)
|
348
|
+
field_instance = self.class.get_field("#{field_definition.name}")
|
349
|
+
context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
|
350
|
+
end
|
351
|
+
RUBY
|
352
|
+
end
|
334
353
|
end
|
335
354
|
end
|
336
355
|
|
337
356
|
def resolve_type(types, ast_node)
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
357
|
+
case ast_node
|
358
|
+
when GraphQL::Language::Nodes::TypeName
|
359
|
+
type_name = ast_node.name
|
360
|
+
types[type_name] ||= GraphQL::Schema::LateBoundType.new(type_name)
|
361
|
+
when GraphQL::Language::Nodes::NonNullType
|
362
|
+
resolve_type(types, ast_node.of_type).to_non_null_type
|
363
|
+
when GraphQL::Language::Nodes::ListType
|
364
|
+
resolve_type(types, ast_node.of_type).to_list_type
|
365
|
+
else
|
366
|
+
raise "Unexpected ast_node: #{ast_node.inspect}"
|
344
367
|
end
|
345
|
-
type
|
346
368
|
end
|
347
369
|
|
348
370
|
def resolve_type_name(type)
|
@@ -2,11 +2,11 @@
|
|
2
2
|
module GraphQL
|
3
3
|
class Schema
|
4
4
|
BUILT_IN_TYPES = {
|
5
|
-
"Int" =>
|
6
|
-
"String" =>
|
7
|
-
"Float" =>
|
8
|
-
"Boolean" =>
|
9
|
-
"ID" =>
|
5
|
+
"Int" => GraphQL::Types::Int,
|
6
|
+
"String" => GraphQL::Types::String,
|
7
|
+
"Float" => GraphQL::Types::Float,
|
8
|
+
"Boolean" => GraphQL::Types::Boolean,
|
9
|
+
"ID" => GraphQL::Types::ID,
|
10
10
|
}
|
11
11
|
end
|
12
12
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class Directive < GraphQL::Schema::Member
|
5
|
+
class Deprecated < GraphQL::Schema::Directive
|
6
|
+
description "Marks an element of a GraphQL schema as no longer supported."
|
7
|
+
locations(GraphQL::Schema::Directive::FIELD_DEFINITION, GraphQL::Schema::Directive::ENUM_VALUE, GraphQL::Schema::Directive::ARGUMENT_DEFINITION, GraphQL::Schema::Directive::INPUT_FIELD_DEFINITION)
|
8
|
+
|
9
|
+
reason_description = "Explains why this element was deprecated, usually also including a "\
|
10
|
+
"suggestion for how to access supported similar data. Formatted "\
|
11
|
+
"in [Markdown](https://daringfireball.net/projects/markdown/)."
|
12
|
+
|
13
|
+
argument :reason, String, reason_description, default_value: Directive::DEFAULT_DEPRECATION_REASON, required: false
|
14
|
+
default_directive true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -9,8 +9,14 @@ module GraphQL
|
|
9
9
|
class Directive < GraphQL::Schema::Member
|
10
10
|
extend GraphQL::Schema::Member::HasArguments
|
11
11
|
class << self
|
12
|
+
# Return a name based on the class name,
|
13
|
+
# but downcase the first letter.
|
12
14
|
def default_graphql_name
|
13
|
-
|
15
|
+
@default_graphql_name ||= begin
|
16
|
+
camelized_name = super
|
17
|
+
camelized_name[0] = camelized_name[0].downcase
|
18
|
+
camelized_name
|
19
|
+
end
|
14
20
|
end
|
15
21
|
|
16
22
|
def locations(*new_locations)
|
@@ -27,26 +33,39 @@ module GraphQL
|
|
27
33
|
elsif @default_directive.nil?
|
28
34
|
@default_directive = (superclass.respond_to?(:default_directive) ? superclass.default_directive : false)
|
29
35
|
else
|
30
|
-
|
36
|
+
!!@default_directive
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
40
|
+
def default_directive?
|
41
|
+
default_directive
|
42
|
+
end
|
43
|
+
|
34
44
|
def to_graphql
|
35
45
|
defn = GraphQL::Directive.new
|
36
46
|
defn.name = self.graphql_name
|
37
47
|
defn.description = self.description
|
38
48
|
defn.locations = self.locations
|
39
49
|
defn.default_directive = self.default_directive
|
50
|
+
defn.ast_node = ast_node
|
40
51
|
defn.metadata[:type_class] = self
|
41
52
|
arguments.each do |name, arg_defn|
|
42
53
|
arg_graphql = arg_defn.to_graphql
|
43
54
|
defn.arguments[arg_graphql.name] = arg_graphql
|
44
55
|
end
|
56
|
+
# Make a reference to a classic-style Arguments class
|
57
|
+
defn.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(defn)
|
58
|
+
|
45
59
|
defn
|
46
60
|
end
|
47
61
|
|
48
62
|
# If false, this part of the query won't be evaluated
|
49
|
-
def include?(_object,
|
63
|
+
def include?(_object, arguments, context)
|
64
|
+
static_include?(arguments, context)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Determines whether {Execution::Lookahead} considers the field to be selected
|
68
|
+
def static_include?(_arguments, _context)
|
50
69
|
true
|
51
70
|
end
|
52
71
|
|
@@ -54,6 +73,18 @@ module GraphQL
|
|
54
73
|
def resolve(object, arguments, context)
|
55
74
|
yield
|
56
75
|
end
|
76
|
+
|
77
|
+
def on_field?
|
78
|
+
locations.include?(FIELD)
|
79
|
+
end
|
80
|
+
|
81
|
+
def on_fragment?
|
82
|
+
locations.include?(FRAGMENT_SPREAD) && locations.include?(INLINE_FRAGMENT)
|
83
|
+
end
|
84
|
+
|
85
|
+
def on_operation?
|
86
|
+
locations.include?(QUERY) && locations.include?(MUTATION) && locations.include?(SUBSCRIPTION)
|
87
|
+
end
|
57
88
|
end
|
58
89
|
|
59
90
|
LOCATIONS = [
|