graphql 2.0.14 → 2.0.32
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.
- checksums.yaml +4 -4
- data/lib/generators/graphql/mutation_delete_generator.rb +1 -1
- data/lib/generators/graphql/mutation_update_generator.rb +1 -1
- data/lib/generators/graphql/relay.rb +18 -1
- data/lib/graphql/analysis/ast/visitor.rb +42 -35
- data/lib/graphql/analysis/ast.rb +2 -2
- data/lib/graphql/backtrace/table.rb +2 -2
- data/lib/graphql/backtrace/trace.rb +96 -0
- data/lib/graphql/backtrace/tracer.rb +1 -1
- data/lib/graphql/backtrace.rb +2 -1
- data/lib/graphql/dataloader/source.rb +69 -45
- data/lib/graphql/dataloader.rb +8 -5
- data/lib/graphql/execution/interpreter/arguments.rb +1 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +33 -33
- data/lib/graphql/execution/interpreter/resolve.rb +19 -0
- data/lib/graphql/execution/interpreter/runtime.rb +355 -268
- data/lib/graphql/execution/interpreter.rb +19 -15
- data/lib/graphql/execution/lazy.rb +6 -12
- data/lib/graphql/execution/lookahead.rb +16 -5
- data/lib/graphql/execution/multiplex.rb +2 -1
- data/lib/graphql/filter.rb +8 -2
- data/lib/graphql/introspection/directive_type.rb +2 -2
- data/lib/graphql/introspection/entry_points.rb +1 -1
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +2 -2
- data/lib/graphql/introspection/type_type.rb +5 -5
- data/lib/graphql/introspection.rb +1 -1
- data/lib/graphql/language/document_from_schema_definition.rb +58 -35
- data/lib/graphql/language/lexer.rb +248 -1505
- data/lib/graphql/language/nodes.rb +69 -40
- data/lib/graphql/language/parser.rb +775 -742
- data/lib/graphql/language/parser.y +44 -38
- data/lib/graphql/language/printer.rb +48 -25
- data/lib/graphql/language/visitor.rb +192 -81
- data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
- data/lib/graphql/pagination/connection.rb +5 -5
- data/lib/graphql/query/context.rb +93 -27
- data/lib/graphql/query/null_context.rb +8 -18
- data/lib/graphql/query/validation_pipeline.rb +2 -1
- data/lib/graphql/query.rb +55 -13
- data/lib/graphql/rake_task.rb +28 -1
- data/lib/graphql/schema/addition.rb +38 -12
- data/lib/graphql/schema/always_visible.rb +10 -0
- data/lib/graphql/schema/argument.rb +15 -23
- data/lib/graphql/schema/build_from_definition.rb +54 -25
- data/lib/graphql/schema/directive/transform.rb +1 -1
- data/lib/graphql/schema/directive.rb +12 -2
- data/lib/graphql/schema/enum.rb +24 -17
- data/lib/graphql/schema/enum_value.rb +3 -4
- data/lib/graphql/schema/field/connection_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +95 -73
- data/lib/graphql/schema/field_extension.rb +1 -4
- data/lib/graphql/schema/find_inherited_value.rb +2 -7
- data/lib/graphql/schema/input_object.rb +9 -7
- data/lib/graphql/schema/interface.rb +5 -11
- data/lib/graphql/schema/introspection_system.rb +1 -1
- data/lib/graphql/schema/late_bound_type.rb +2 -0
- data/lib/graphql/schema/member/base_dsl_methods.rb +17 -14
- data/lib/graphql/schema/member/build_type.rb +11 -3
- data/lib/graphql/schema/member/has_arguments.rb +114 -65
- data/lib/graphql/schema/member/has_ast_node.rb +12 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
- data/lib/graphql/schema/member/has_directives.rb +81 -61
- data/lib/graphql/schema/member/has_fields.rb +95 -38
- data/lib/graphql/schema/member/has_interfaces.rb +49 -8
- data/lib/graphql/schema/member/has_validators.rb +32 -6
- data/lib/graphql/schema/member/relay_shortcuts.rb +19 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
- data/lib/graphql/schema/object.rb +8 -5
- data/lib/graphql/schema/printer.rb +3 -1
- data/lib/graphql/schema/relay_classic_mutation.rb +1 -1
- data/lib/graphql/schema/resolver/has_payload_type.rb +9 -9
- data/lib/graphql/schema/resolver.rb +16 -14
- data/lib/graphql/schema/timeout.rb +25 -29
- data/lib/graphql/schema/type_membership.rb +3 -0
- data/lib/graphql/schema/union.rb +10 -1
- data/lib/graphql/schema/validator.rb +2 -2
- data/lib/graphql/schema/warden.rb +64 -7
- data/lib/graphql/schema.rb +171 -28
- data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
- data/lib/graphql/static_validation/literal_validator.rb +15 -1
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
- data/lib/graphql/static_validation/validator.rb +1 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -1
- data/lib/graphql/subscriptions/event.rb +2 -7
- data/lib/graphql/subscriptions.rb +5 -0
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/appoptics_trace.rb +255 -0
- data/lib/graphql/tracing/appsignal_trace.rb +81 -0
- data/lib/graphql/tracing/data_dog_trace.rb +187 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +7 -21
- data/lib/graphql/tracing/legacy_trace.rb +69 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/notifications_trace.rb +49 -0
- data/lib/graphql/tracing/platform_trace.rb +123 -0
- data/lib/graphql/tracing/platform_tracing.rb +15 -3
- data/lib/graphql/tracing/prometheus_trace.rb +93 -0
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +1 -1
- data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
- data/lib/graphql/tracing/scout_trace.rb +75 -0
- data/lib/graphql/tracing/statsd_trace.rb +60 -0
- data/lib/graphql/tracing/trace.rb +75 -0
- data/lib/graphql/tracing.rb +17 -39
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/relay/base_connection.rb +1 -1
- data/lib/graphql/types/relay/connection_behaviors.rb +28 -6
- data/lib/graphql/types/relay/edge_behaviors.rb +16 -5
- data/lib/graphql/types/relay/node_behaviors.rb +8 -2
- data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
- data/lib/graphql/types/relay.rb +0 -1
- data/lib/graphql/types/string.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +16 -9
- data/readme.md +1 -1
- metadata +66 -29
- data/lib/graphql/language/lexer.rl +0 -280
- data/lib/graphql/types/relay/default_relay.rb +0 -21
|
@@ -14,7 +14,7 @@ module GraphQL
|
|
|
14
14
|
class << self
|
|
15
15
|
# Used internally to signal that the query shouldn't be executed
|
|
16
16
|
# @api private
|
|
17
|
-
NO_OPERATION =
|
|
17
|
+
NO_OPERATION = GraphQL::EmptyObjects::EMPTY_HASH
|
|
18
18
|
|
|
19
19
|
# @param schema [GraphQL::Schema]
|
|
20
20
|
# @param queries [Array<GraphQL::Query, Hash>]
|
|
@@ -34,11 +34,12 @@ module GraphQL
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
multiplex = Execution::Multiplex.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
|
|
37
|
-
multiplex.
|
|
37
|
+
multiplex.current_trace.execute_multiplex(multiplex: multiplex) do
|
|
38
38
|
schema = multiplex.schema
|
|
39
39
|
queries = multiplex.queries
|
|
40
40
|
query_instrumenters = schema.instrumenters[:query]
|
|
41
41
|
multiplex_instrumenters = schema.instrumenters[:multiplex]
|
|
42
|
+
lazies_at_depth = Hash.new { |h, k| h[k] = [] }
|
|
42
43
|
|
|
43
44
|
# First, run multiplex instrumentation, then query instrumentation for each query
|
|
44
45
|
call_hooks(multiplex_instrumenters, multiplex, :before_multiplex, :after_multiplex) do
|
|
@@ -67,10 +68,10 @@ module GraphQL
|
|
|
67
68
|
# Although queries in a multiplex _share_ an Interpreter instance,
|
|
68
69
|
# they also have another item of state, which is private to that query
|
|
69
70
|
# in particular, assign it here:
|
|
70
|
-
runtime = Runtime.new(query: query)
|
|
71
|
-
query.context.namespace(:
|
|
71
|
+
runtime = Runtime.new(query: query, lazies_at_depth: lazies_at_depth)
|
|
72
|
+
query.context.namespace(:interpreter_runtime)[:runtime] = runtime
|
|
72
73
|
|
|
73
|
-
query.
|
|
74
|
+
query.current_trace.execute_query(query: query) do
|
|
74
75
|
runtime.run_eager
|
|
75
76
|
end
|
|
76
77
|
rescue GraphQL::ExecutionError => err
|
|
@@ -86,25 +87,21 @@ module GraphQL
|
|
|
86
87
|
|
|
87
88
|
# Then, work through lazy results in a breadth-first way
|
|
88
89
|
multiplex.dataloader.append_job {
|
|
89
|
-
tracer = multiplex
|
|
90
90
|
query = multiplex.queries.length == 1 ? multiplex.queries[0] : nil
|
|
91
91
|
queries = multiplex ? multiplex.queries : [query]
|
|
92
92
|
final_values = queries.map do |query|
|
|
93
|
-
runtime = query.context.namespace(:
|
|
93
|
+
runtime = query.context.namespace(:interpreter_runtime)[:runtime]
|
|
94
94
|
# it might not be present if the query has an error
|
|
95
95
|
runtime ? runtime.final_result : nil
|
|
96
96
|
end
|
|
97
97
|
final_values.compact!
|
|
98
|
-
|
|
99
|
-
Interpreter::Resolve.
|
|
98
|
+
multiplex.current_trace.execute_query_lazy(multiplex: multiplex, query: query) do
|
|
99
|
+
Interpreter::Resolve.resolve_each_depth(lazies_at_depth, multiplex.dataloader)
|
|
100
100
|
end
|
|
101
101
|
queries.each do |query|
|
|
102
|
-
runtime = query.context.namespace(:
|
|
102
|
+
runtime = query.context.namespace(:interpreter_runtime)[:runtime]
|
|
103
103
|
if runtime
|
|
104
|
-
runtime.
|
|
105
|
-
runtime.delete_interpreter_context(:current_field)
|
|
106
|
-
runtime.delete_interpreter_context(:current_object)
|
|
107
|
-
runtime.delete_interpreter_context(:current_arguments)
|
|
104
|
+
runtime.delete_all_interpreter_context
|
|
108
105
|
end
|
|
109
106
|
end
|
|
110
107
|
}
|
|
@@ -123,7 +120,7 @@ module GraphQL
|
|
|
123
120
|
end
|
|
124
121
|
else
|
|
125
122
|
result = {
|
|
126
|
-
"data" => query.context.namespace(:
|
|
123
|
+
"data" => query.context.namespace(:interpreter_runtime)[:runtime].final_result
|
|
127
124
|
}
|
|
128
125
|
|
|
129
126
|
if query.context.errors.any?
|
|
@@ -146,6 +143,13 @@ module GraphQL
|
|
|
146
143
|
# Assign values here so that the query's `@executed` becomes true
|
|
147
144
|
queries.map { |q| q.result_values ||= {} }
|
|
148
145
|
raise
|
|
146
|
+
ensure
|
|
147
|
+
queries.map { |query|
|
|
148
|
+
runtime = query.context.namespace(:interpreter_runtime)[:runtime]
|
|
149
|
+
if runtime
|
|
150
|
+
runtime.delete_all_interpreter_context
|
|
151
|
+
end
|
|
152
|
+
}
|
|
149
153
|
end
|
|
150
154
|
end
|
|
151
155
|
end
|
|
@@ -12,16 +12,14 @@ module GraphQL
|
|
|
12
12
|
# - It has no error-catching functionality
|
|
13
13
|
# @api private
|
|
14
14
|
class Lazy
|
|
15
|
-
attr_reader :
|
|
15
|
+
attr_reader :field
|
|
16
16
|
|
|
17
17
|
# Create a {Lazy} which will get its inner value by calling the block
|
|
18
|
-
# @param path [Array<String, Integer>]
|
|
19
18
|
# @param field [GraphQL::Schema::Field]
|
|
20
19
|
# @param get_value_func [Proc] a block to get the inner value (later)
|
|
21
|
-
def initialize(
|
|
20
|
+
def initialize(field: nil, &get_value_func)
|
|
22
21
|
@get_value_func = get_value_func
|
|
23
22
|
@resolved = false
|
|
24
|
-
@path = path
|
|
25
23
|
@field = field
|
|
26
24
|
end
|
|
27
25
|
|
|
@@ -29,15 +27,11 @@ module GraphQL
|
|
|
29
27
|
def value
|
|
30
28
|
if !@resolved
|
|
31
29
|
@resolved = true
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
v = v.value
|
|
36
|
-
end
|
|
37
|
-
v
|
|
38
|
-
rescue GraphQL::ExecutionError => err
|
|
39
|
-
err
|
|
30
|
+
v = @get_value_func.call
|
|
31
|
+
if v.is_a?(Lazy)
|
|
32
|
+
v = v.value
|
|
40
33
|
end
|
|
34
|
+
@value = v
|
|
41
35
|
end
|
|
42
36
|
|
|
43
37
|
# `SKIP` was made into a subclass of `GraphQL::Error` to improve runtime performance
|
|
@@ -55,7 +55,7 @@ module GraphQL
|
|
|
55
55
|
@arguments
|
|
56
56
|
else
|
|
57
57
|
@arguments = if @field
|
|
58
|
-
@query.
|
|
58
|
+
@query.after_lazy(@query.arguments_for(@ast_nodes.first, @field)) do |args|
|
|
59
59
|
args.is_a?(Execution::Interpreter::Arguments) ? args.keyword_arguments : args
|
|
60
60
|
end
|
|
61
61
|
else
|
|
@@ -76,8 +76,8 @@ module GraphQL
|
|
|
76
76
|
# @param field_name [String, Symbol]
|
|
77
77
|
# @param arguments [Hash] Arguments which must match in the selection
|
|
78
78
|
# @return [Boolean]
|
|
79
|
-
def selects?(field_name, arguments: nil)
|
|
80
|
-
selection(field_name, arguments: arguments).selected?
|
|
79
|
+
def selects?(field_name, selected_type: @selected_type, arguments: nil)
|
|
80
|
+
selection(field_name, selected_type: selected_type, arguments: arguments).selected?
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
# @return [Boolean] True if this lookahead represents a field that was requested
|
|
@@ -95,11 +95,22 @@ module GraphQL
|
|
|
95
95
|
@query.get_field(selected_type, field_name)
|
|
96
96
|
when Symbol
|
|
97
97
|
# Try to avoid the `.to_s` below, if possible
|
|
98
|
-
all_fields =
|
|
98
|
+
all_fields = if selected_type.kind.fields?
|
|
99
|
+
@query.warden.fields(selected_type)
|
|
100
|
+
else
|
|
101
|
+
# Handle unions by checking possible
|
|
102
|
+
@query.warden
|
|
103
|
+
.possible_types(selected_type)
|
|
104
|
+
.map { |t| @query.warden.fields(t) }
|
|
105
|
+
.flatten
|
|
106
|
+
end
|
|
107
|
+
|
|
99
108
|
if (match_by_orig_name = all_fields.find { |f| f.original_name == field_name })
|
|
100
109
|
match_by_orig_name
|
|
101
110
|
else
|
|
102
|
-
|
|
111
|
+
# Symbol#name is only present on 3.0+
|
|
112
|
+
sym_s = field_name.respond_to?(:name) ? field_name.name : field_name.to_s
|
|
113
|
+
guessed_name = Schema::Member::BuildType.camelize(sym_s)
|
|
103
114
|
@query.get_field(selected_type, guessed_name)
|
|
104
115
|
end
|
|
105
116
|
end
|
|
@@ -25,13 +25,14 @@ module GraphQL
|
|
|
25
25
|
class Multiplex
|
|
26
26
|
include Tracing::Traceable
|
|
27
27
|
|
|
28
|
-
attr_reader :context, :queries, :schema, :max_complexity, :dataloader
|
|
28
|
+
attr_reader :context, :queries, :schema, :max_complexity, :dataloader, :current_trace
|
|
29
29
|
|
|
30
30
|
def initialize(schema:, queries:, context:, max_complexity:)
|
|
31
31
|
@schema = schema
|
|
32
32
|
@queries = queries
|
|
33
33
|
@queries.each { |q| q.multiplex = self }
|
|
34
34
|
@context = context
|
|
35
|
+
@current_trace = @context[:trace] || schema.new_trace(multiplex: self)
|
|
35
36
|
@dataloader = @context[:dataloader] ||= @schema.dataloader_class.new
|
|
36
37
|
@tracers = schema.tracers + (context[:tracers] || [])
|
|
37
38
|
# Support `context: {backtrace: true}`
|
data/lib/graphql/filter.rb
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
require "graphql/deprecation"
|
|
3
|
+
|
|
2
4
|
module GraphQL
|
|
3
5
|
# @api private
|
|
4
6
|
class Filter
|
|
5
|
-
def initialize(only: nil, except: nil)
|
|
7
|
+
def initialize(only: nil, except: nil, silence_deprecation_warning: false)
|
|
8
|
+
if !silence_deprecation_warning
|
|
9
|
+
line = caller(2, 10).find { |l| !l.include?("lib/graphql") }
|
|
10
|
+
GraphQL::Deprecation.warn("GraphQL::Filter, `only:`, `except:`, and `.merge_filters` are deprecated and will be removed in v2.1.0. Implement `visible?` on your schema members instead (https://graphql-ruby.org/authorization/visibility.html).\n #{line}")
|
|
11
|
+
end
|
|
6
12
|
@only = only
|
|
7
13
|
@except = except
|
|
8
14
|
end
|
|
@@ -17,7 +23,7 @@ module GraphQL
|
|
|
17
23
|
onlies = [self].concat(Array(only))
|
|
18
24
|
merged_only = MergedOnly.build(onlies)
|
|
19
25
|
merged_except = MergedExcept.build(Array(except))
|
|
20
|
-
self.class.new(only: merged_only, except: merged_except)
|
|
26
|
+
self.class.new(only: merged_only, except: merged_except, silence_deprecation_warning: true)
|
|
21
27
|
end
|
|
22
28
|
|
|
23
29
|
private
|
|
@@ -11,8 +11,8 @@ module GraphQL
|
|
|
11
11
|
"to the executor."
|
|
12
12
|
field :name, String, null: false, method: :graphql_name
|
|
13
13
|
field :description, String
|
|
14
|
-
field :locations, [GraphQL::Schema::LateBoundType.new("__DirectiveLocation")], null: false
|
|
15
|
-
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false do
|
|
14
|
+
field :locations, [GraphQL::Schema::LateBoundType.new("__DirectiveLocation")], null: false, scope: false
|
|
15
|
+
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false, scope: false do
|
|
16
16
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
|
17
17
|
end
|
|
18
18
|
field :on_operation, Boolean, null: false, deprecation_reason: "Use `locations`.", method: :on_operation?
|
|
@@ -11,7 +11,7 @@ module GraphQL
|
|
|
11
11
|
# Apply wrapping manually since this field isn't wrapped by instrumentation
|
|
12
12
|
schema = @context.query.schema
|
|
13
13
|
schema_type = schema.introspection_system.types["__Schema"]
|
|
14
|
-
schema_type.
|
|
14
|
+
schema_type.wrap(schema, @context)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def __type(name:)
|
|
@@ -7,7 +7,7 @@ module GraphQL
|
|
|
7
7
|
"a name, potentially a list of arguments, and a return type."
|
|
8
8
|
field :name, String, null: false
|
|
9
9
|
field :description, String
|
|
10
|
-
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false do
|
|
10
|
+
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false, scope: false do
|
|
11
11
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
|
12
12
|
end
|
|
13
13
|
field :type, GraphQL::Schema::LateBoundType.new("__Type"), null: false
|
|
@@ -8,11 +8,11 @@ module GraphQL
|
|
|
8
8
|
"available types and directives on the server, as well as the entry points for "\
|
|
9
9
|
"query, mutation, and subscription operations."
|
|
10
10
|
|
|
11
|
-
field :types, [GraphQL::Schema::LateBoundType.new("__Type")], "A list of all types supported by this server.", null: false
|
|
11
|
+
field :types, [GraphQL::Schema::LateBoundType.new("__Type")], "A list of all types supported by this server.", null: false, scope: false
|
|
12
12
|
field :query_type, GraphQL::Schema::LateBoundType.new("__Type"), "The type that query operations will be rooted at.", null: false
|
|
13
13
|
field :mutation_type, GraphQL::Schema::LateBoundType.new("__Type"), "If this server supports mutation, the type that mutation operations will be rooted at."
|
|
14
14
|
field :subscription_type, GraphQL::Schema::LateBoundType.new("__Type"), "If this server support subscription, the type that subscription operations will be rooted at."
|
|
15
|
-
field :directives, [GraphQL::Schema::LateBoundType.new("__Directive")], "A list of all directives supported by this server.", null: false
|
|
15
|
+
field :directives, [GraphQL::Schema::LateBoundType.new("__Directive")], "A list of all directives supported by this server.", null: false, scope: false
|
|
16
16
|
field :description, String, resolver_method: :schema_description
|
|
17
17
|
|
|
18
18
|
def schema_description
|
|
@@ -14,15 +14,15 @@ module GraphQL
|
|
|
14
14
|
field :kind, GraphQL::Schema::LateBoundType.new("__TypeKind"), null: false
|
|
15
15
|
field :name, String, method: :graphql_name
|
|
16
16
|
field :description, String
|
|
17
|
-
field :fields, [GraphQL::Schema::LateBoundType.new("__Field")] do
|
|
17
|
+
field :fields, [GraphQL::Schema::LateBoundType.new("__Field")], scope: false do
|
|
18
18
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
|
19
19
|
end
|
|
20
|
-
field :interfaces, [GraphQL::Schema::LateBoundType.new("__Type")]
|
|
21
|
-
field :possible_types, [GraphQL::Schema::LateBoundType.new("__Type")]
|
|
22
|
-
field :enum_values, [GraphQL::Schema::LateBoundType.new("__EnumValue")] do
|
|
20
|
+
field :interfaces, [GraphQL::Schema::LateBoundType.new("__Type")], scope: false
|
|
21
|
+
field :possible_types, [GraphQL::Schema::LateBoundType.new("__Type")], scope: false
|
|
22
|
+
field :enum_values, [GraphQL::Schema::LateBoundType.new("__EnumValue")], scope: false do
|
|
23
23
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
|
24
24
|
end
|
|
25
|
-
field :input_fields, [GraphQL::Schema::LateBoundType.new("__InputValue")] do
|
|
25
|
+
field :input_fields, [GraphQL::Schema::LateBoundType.new("__InputValue")], scope: false do
|
|
26
26
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
|
27
27
|
end
|
|
28
28
|
field :of_type, GraphQL::Schema::LateBoundType.new("__Type")
|
|
@@ -4,7 +4,7 @@ module GraphQL
|
|
|
4
4
|
def self.query(include_deprecated_args: false, include_schema_description: false, include_is_repeatable: false, include_specified_by_url: false, include_is_one_of: false)
|
|
5
5
|
# The introspection query to end all introspection queries, copied from
|
|
6
6
|
# https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js
|
|
7
|
-
<<-QUERY
|
|
7
|
+
<<-QUERY.gsub(/\n{2,}/, "\n")
|
|
8
8
|
query IntrospectionQuery {
|
|
9
9
|
__schema {
|
|
10
10
|
#{include_schema_description ? "description" : ""}
|
|
@@ -22,18 +22,26 @@ module GraphQL
|
|
|
22
22
|
@include_introspection_types = include_introspection_types
|
|
23
23
|
@include_built_in_scalars = include_built_in_scalars
|
|
24
24
|
@include_built_in_directives = include_built_in_directives
|
|
25
|
+
@include_one_of = false
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
schema_context = schema.context_class.new(query: nil, object: nil, schema: schema, values: context)
|
|
28
|
+
|
|
29
|
+
@warden = if only || except
|
|
30
|
+
filter = GraphQL::Filter
|
|
31
|
+
.new(only: only, except: except)
|
|
32
|
+
.merge(only: @schema.method(:visible?))
|
|
33
|
+
GraphQL::Schema::Warden.new(
|
|
34
|
+
filter,
|
|
35
|
+
schema: @schema,
|
|
36
|
+
context: schema_context,
|
|
37
|
+
)
|
|
38
|
+
else
|
|
39
|
+
@schema.warden_class.new(
|
|
40
|
+
schema: @schema,
|
|
41
|
+
context: schema_context,
|
|
42
|
+
)
|
|
29
43
|
end
|
|
30
44
|
|
|
31
|
-
schema_context = schema.context_class.new(query: nil, object: nil, schema: schema, values: context)
|
|
32
|
-
@warden = GraphQL::Schema::Warden.new(
|
|
33
|
-
filter,
|
|
34
|
-
schema: @schema,
|
|
35
|
-
context: schema_context,
|
|
36
|
-
)
|
|
37
45
|
schema_context.warden = @warden
|
|
38
46
|
end
|
|
39
47
|
|
|
@@ -44,16 +52,18 @@ module GraphQL
|
|
|
44
52
|
end
|
|
45
53
|
|
|
46
54
|
def build_schema_node
|
|
47
|
-
|
|
48
|
-
query: (q = warden.root_type_for_operation("query")) && q.graphql_name,
|
|
49
|
-
mutation: (m = warden.root_type_for_operation("mutation")) && m.graphql_name,
|
|
50
|
-
subscription: (s = warden.root_type_for_operation("subscription")) && s.graphql_name,
|
|
51
|
-
# This only supports directives from parsing,
|
|
52
|
-
# use a custom printer to add to this list.
|
|
53
|
-
#
|
|
55
|
+
schema_options = {
|
|
54
56
|
# `@schema.directives` is covered by `build_definition_nodes`
|
|
55
|
-
directives:
|
|
56
|
-
|
|
57
|
+
directives: definition_directives(@schema, :schema_directives),
|
|
58
|
+
}
|
|
59
|
+
if !schema_respects_root_name_conventions?(@schema)
|
|
60
|
+
schema_options.merge!({
|
|
61
|
+
query: (q = warden.root_type_for_operation("query")) && q.graphql_name,
|
|
62
|
+
mutation: (m = warden.root_type_for_operation("mutation")) && m.graphql_name,
|
|
63
|
+
subscription: (s = warden.root_type_for_operation("subscription")) && s.graphql_name,
|
|
64
|
+
})
|
|
65
|
+
end
|
|
66
|
+
GraphQL::Language::Nodes::SchemaDefinition.new(schema_options)
|
|
57
67
|
end
|
|
58
68
|
|
|
59
69
|
def build_object_type_node(object_type)
|
|
@@ -243,20 +253,30 @@ module GraphQL
|
|
|
243
253
|
end
|
|
244
254
|
|
|
245
255
|
def build_directive_nodes(directives)
|
|
246
|
-
if !include_built_in_directives
|
|
247
|
-
directives = directives.reject { |directive| directive.default_directive? }
|
|
248
|
-
end
|
|
249
|
-
|
|
250
256
|
directives
|
|
251
257
|
.map { |directive| build_directive_node(directive) }
|
|
252
258
|
.sort_by(&:name)
|
|
253
259
|
end
|
|
254
260
|
|
|
255
261
|
def build_definition_nodes
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
262
|
+
dirs_to_build = warden.directives
|
|
263
|
+
if !include_built_in_directives
|
|
264
|
+
dirs_to_build = dirs_to_build.reject { |directive| directive.default_directive? }
|
|
265
|
+
end
|
|
266
|
+
dir_nodes = build_directive_nodes(dirs_to_build)
|
|
267
|
+
|
|
268
|
+
type_nodes = build_type_definition_nodes(warden.reachable_types)
|
|
269
|
+
|
|
270
|
+
if @include_one_of
|
|
271
|
+
# This may have been set to true when iterating over all types
|
|
272
|
+
dir_nodes.concat(build_directive_nodes([GraphQL::Schema::Directive::OneOf]))
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
definitions = [*dir_nodes, *type_nodes]
|
|
276
|
+
if include_schema_node?
|
|
277
|
+
definitions.unshift(build_schema_node)
|
|
278
|
+
end
|
|
279
|
+
|
|
260
280
|
definitions
|
|
261
281
|
end
|
|
262
282
|
|
|
@@ -283,7 +303,9 @@ module GraphQL
|
|
|
283
303
|
private
|
|
284
304
|
|
|
285
305
|
def include_schema_node?
|
|
286
|
-
always_include_schema ||
|
|
306
|
+
always_include_schema ||
|
|
307
|
+
!schema_respects_root_name_conventions?(schema) ||
|
|
308
|
+
!schema.schema_directives.empty?
|
|
287
309
|
end
|
|
288
310
|
|
|
289
311
|
def schema_respects_root_name_conventions?(schema)
|
|
@@ -293,14 +315,14 @@ module GraphQL
|
|
|
293
315
|
end
|
|
294
316
|
|
|
295
317
|
def directives(member)
|
|
296
|
-
definition_directives(member)
|
|
318
|
+
definition_directives(member, :directives)
|
|
297
319
|
end
|
|
298
320
|
|
|
299
|
-
def definition_directives(member)
|
|
300
|
-
dirs = if !member.respond_to?(
|
|
321
|
+
def definition_directives(member, directives_method)
|
|
322
|
+
dirs = if !member.respond_to?(directives_method) || member.directives.empty?
|
|
301
323
|
[]
|
|
302
324
|
else
|
|
303
|
-
member.
|
|
325
|
+
member.public_send(directives_method).map do |dir|
|
|
304
326
|
args = []
|
|
305
327
|
dir.arguments.argument_values.each_value do |arg_value| # rubocop:disable Development/ContextIsPassedCop -- directive instance method
|
|
306
328
|
arg_defn = arg_value.definition
|
|
@@ -314,6 +336,11 @@ module GraphQL
|
|
|
314
336
|
)
|
|
315
337
|
end
|
|
316
338
|
end
|
|
339
|
+
|
|
340
|
+
# If this schema uses this built-in directive definition,
|
|
341
|
+
# include it in the print-out since it's not part of the spec yet.
|
|
342
|
+
@include_one_of ||= dir.class == GraphQL::Schema::Directive::OneOf
|
|
343
|
+
|
|
317
344
|
GraphQL::Language::Nodes::Directive.new(
|
|
318
345
|
name: dir.class.graphql_name,
|
|
319
346
|
arguments: args
|
|
@@ -324,10 +351,6 @@ module GraphQL
|
|
|
324
351
|
dirs
|
|
325
352
|
end
|
|
326
353
|
|
|
327
|
-
def ast_directives(member)
|
|
328
|
-
member.ast_node ? member.ast_node.directives : []
|
|
329
|
-
end
|
|
330
|
-
|
|
331
354
|
attr_reader :schema, :warden, :always_include_schema,
|
|
332
355
|
:include_introspection_types, :include_built_in_directives, :include_built_in_scalars
|
|
333
356
|
end
|