graphql 1.12.24 → 1.13.19
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 +3 -8
- data/lib/generators/graphql/enum_generator.rb +4 -10
- data/lib/generators/graphql/field_extractor.rb +31 -0
- data/lib/generators/graphql/input_generator.rb +50 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
- data/lib/generators/graphql/install_generator.rb +10 -3
- data/lib/generators/graphql/interface_generator.rb +7 -7
- data/lib/generators/graphql/mutation_create_generator.rb +22 -0
- data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
- data/lib/generators/graphql/mutation_generator.rb +5 -30
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +8 -37
- data/lib/generators/graphql/orm_mutations_base.rb +40 -0
- data/lib/generators/graphql/scalar_generator.rb +4 -2
- data/lib/generators/graphql/templates/enum.erb +5 -1
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +4 -2
- data/lib/generators/graphql/templates/mutation.erb +1 -1
- data/lib/generators/graphql/templates/mutation_create.erb +20 -0
- data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
- data/lib/generators/graphql/templates/mutation_update.erb +21 -0
- data/lib/generators/graphql/templates/object.erb +4 -2
- data/lib/generators/graphql/templates/scalar.erb +3 -1
- data/lib/generators/graphql/templates/union.erb +4 -2
- data/lib/generators/graphql/type_generator.rb +46 -10
- data/lib/generators/graphql/union_generator.rb +5 -5
- data/lib/graphql/analysis/ast/field_usage.rb +2 -2
- data/lib/graphql/analysis/ast/query_complexity.rb +10 -14
- data/lib/graphql/analysis/ast/visitor.rb +5 -4
- data/lib/graphql/argument.rb +1 -1
- data/lib/graphql/backtrace/table.rb +1 -1
- data/lib/graphql/base_type.rb +5 -3
- data/lib/graphql/boolean_type.rb +1 -1
- data/lib/graphql/dataloader/source.rb +2 -2
- data/lib/graphql/dataloader.rb +55 -22
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/define/instance_definable.rb +15 -0
- data/lib/graphql/directive/deprecated_directive.rb +1 -1
- data/lib/graphql/directive/include_directive.rb +1 -1
- data/lib/graphql/directive/skip_directive.rb +1 -1
- data/lib/graphql/directive.rb +1 -5
- data/lib/graphql/enum_type.rb +7 -3
- data/lib/graphql/execution/errors.rb +1 -0
- data/lib/graphql/execution/interpreter/arguments.rb +1 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +6 -4
- data/lib/graphql/execution/interpreter/runtime.rb +66 -38
- data/lib/graphql/execution/lookahead.rb +2 -2
- data/lib/graphql/execution/multiplex.rb +4 -1
- data/lib/graphql/field.rb +1 -1
- data/lib/graphql/float_type.rb +1 -1
- data/lib/graphql/id_type.rb +1 -1
- data/lib/graphql/input_object_type.rb +1 -1
- data/lib/graphql/int_type.rb +1 -1
- data/lib/graphql/interface_type.rb +1 -1
- data/lib/graphql/introspection/directive_location_enum.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +5 -3
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +3 -3
- data/lib/graphql/introspection/input_value_type.rb +4 -4
- data/lib/graphql/introspection/schema_type.rb +9 -4
- data/lib/graphql/introspection/type_type.rb +18 -12
- data/lib/graphql/introspection.rb +4 -1
- data/lib/graphql/language/block_string.rb +2 -6
- data/lib/graphql/language/document_from_schema_definition.rb +11 -4
- data/lib/graphql/language/lexer.rb +50 -28
- data/lib/graphql/language/lexer.rl +2 -4
- data/lib/graphql/language/nodes.rb +4 -3
- data/lib/graphql/language/parser.rb +841 -820
- data/lib/graphql/language/parser.y +13 -6
- data/lib/graphql/language/printer.rb +10 -1
- data/lib/graphql/language/sanitized_printer.rb +5 -5
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/name_validator.rb +0 -4
- data/lib/graphql/object_type.rb +2 -2
- data/lib/graphql/pagination/active_record_relation_connection.rb +43 -6
- data/lib/graphql/pagination/relation_connection.rb +59 -29
- data/lib/graphql/query/arguments.rb +1 -1
- data/lib/graphql/query/arguments_cache.rb +1 -1
- data/lib/graphql/query/context.rb +15 -2
- data/lib/graphql/query/input_validation_result.rb +9 -0
- data/lib/graphql/query/literal_input.rb +1 -1
- data/lib/graphql/query/null_context.rb +12 -7
- data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
- data/lib/graphql/query/validation_pipeline.rb +2 -3
- data/lib/graphql/query/variable_validation_error.rb +2 -2
- data/lib/graphql/query/variables.rb +35 -4
- data/lib/graphql/query.rb +0 -1
- data/lib/graphql/relay/connection_type.rb +15 -2
- data/lib/graphql/relay/edges_instrumentation.rb +0 -1
- data/lib/graphql/relay/global_id_resolve.rb +1 -2
- data/lib/graphql/relay/mutation.rb +1 -1
- data/lib/graphql/relay/page_info.rb +1 -1
- data/lib/graphql/relay/range_add.rb +4 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/scalar_type.rb +1 -1
- data/lib/graphql/schema/addition.rb +37 -28
- data/lib/graphql/schema/argument.rb +30 -15
- data/lib/graphql/schema/build_from_definition.rb +6 -5
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +2 -2
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/transform.rb +1 -1
- data/lib/graphql/schema/directive.rb +23 -4
- data/lib/graphql/schema/enum.rb +61 -12
- data/lib/graphql/schema/enum_value.rb +6 -0
- data/lib/graphql/schema/field/connection_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +261 -83
- data/lib/graphql/schema/field_extension.rb +89 -2
- data/lib/graphql/schema/find_inherited_value.rb +1 -0
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/input_object.rb +24 -7
- data/lib/graphql/schema/interface.rb +11 -20
- data/lib/graphql/schema/introspection_system.rb +1 -1
- data/lib/graphql/schema/list.rb +21 -4
- data/lib/graphql/schema/loader.rb +3 -0
- data/lib/graphql/schema/member/accepts_definition.rb +15 -3
- data/lib/graphql/schema/member/base_dsl_methods.rb +1 -1
- data/lib/graphql/schema/member/build_type.rb +0 -4
- data/lib/graphql/schema/member/cached_graphql_definition.rb +29 -2
- data/lib/graphql/schema/member/has_arguments.rb +56 -14
- data/lib/graphql/schema/member/has_deprecation_reason.rb +1 -1
- data/lib/graphql/schema/member/has_fields.rb +76 -18
- data/lib/graphql/schema/member/has_interfaces.rb +100 -0
- data/lib/graphql/schema/member/validates_input.rb +2 -2
- data/lib/graphql/schema/member.rb +1 -0
- data/lib/graphql/schema/non_null.rb +9 -3
- data/lib/graphql/schema/object.rb +10 -75
- data/lib/graphql/schema/printer.rb +1 -1
- data/lib/graphql/schema/relay_classic_mutation.rb +37 -3
- data/lib/graphql/schema/resolver/has_payload_type.rb +27 -2
- data/lib/graphql/schema/resolver.rb +37 -17
- data/lib/graphql/schema/scalar.rb +15 -1
- data/lib/graphql/schema/subscription.rb +11 -1
- data/lib/graphql/schema/traversal.rb +1 -1
- data/lib/graphql/schema/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +18 -4
- data/lib/graphql/schema/union.rb +8 -1
- data/lib/graphql/schema/validator/format_validator.rb +0 -4
- data/lib/graphql/schema/validator/numericality_validator.rb +1 -0
- data/lib/graphql/schema/validator/required_validator.rb +29 -15
- data/lib/graphql/schema/validator.rb +4 -7
- data/lib/graphql/schema/warden.rb +126 -53
- data/lib/graphql/schema.rb +120 -24
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/base_visitor.rb +6 -6
- data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
- data/lib/graphql/static_validation/literal_validator.rb +1 -1
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +1 -1
- data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +3 -3
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -4
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +13 -7
- data/lib/graphql/static_validation/validation_context.rb +4 -0
- data/lib/graphql/string_type.rb +1 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +8 -4
- data/lib/graphql/subscriptions/event.rb +20 -12
- data/lib/graphql/subscriptions/serialize.rb +22 -2
- data/lib/graphql/subscriptions.rb +17 -19
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +6 -20
- data/lib/graphql/tracing/data_dog_tracing.rb +24 -2
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_tracing.rb +20 -10
- data/lib/graphql/types/iso_8601_date.rb +13 -5
- data/lib/graphql/types/iso_8601_date_time.rb +8 -1
- data/lib/graphql/types/relay/connection_behaviors.rb +28 -10
- data/lib/graphql/types/relay/default_relay.rb +5 -1
- data/lib/graphql/types/relay/edge_behaviors.rb +13 -2
- data/lib/graphql/types/relay/has_node_field.rb +1 -1
- data/lib/graphql/types/relay/has_nodes_field.rb +1 -1
- data/lib/graphql/types/relay/node_field.rb +2 -3
- data/lib/graphql/types/relay/nodes_field.rb +19 -3
- data/lib/graphql/types/string.rb +1 -1
- data/lib/graphql/union_type.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +22 -32
- metadata +31 -11
- /data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +0 -0
- /data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +0 -0
@@ -8,14 +8,28 @@ require_relative 'core'
|
|
8
8
|
|
9
9
|
module Graphql
|
10
10
|
module Generators
|
11
|
-
class TypeGeneratorBase < Rails::Generators::
|
11
|
+
class TypeGeneratorBase < Rails::Generators::NamedBase
|
12
12
|
include Core
|
13
13
|
|
14
|
-
|
15
|
-
type: :
|
16
|
-
required:
|
17
|
-
|
18
|
-
|
14
|
+
class_option 'namespaced_types',
|
15
|
+
type: :boolean,
|
16
|
+
required: false,
|
17
|
+
default: false,
|
18
|
+
banner: "Namespaced",
|
19
|
+
desc: "If the generated types will be namespaced"
|
20
|
+
|
21
|
+
argument :custom_fields,
|
22
|
+
type: :array,
|
23
|
+
default: [],
|
24
|
+
banner: "name:type name:type ...",
|
25
|
+
desc: "Fields for this object (type may be expressed as Ruby or GraphQL)"
|
26
|
+
|
27
|
+
|
28
|
+
attr_accessor :graphql_type
|
29
|
+
|
30
|
+
def create_type_file
|
31
|
+
template "#{graphql_type}.erb", "#{options[:directory]}/types#{subdirectory}/#{type_file_name}.rb"
|
32
|
+
end
|
19
33
|
|
20
34
|
# Take a type expression in any combination of GraphQL or Ruby styles
|
21
35
|
# and return it in a specified output style
|
@@ -61,12 +75,12 @@ module Graphql
|
|
61
75
|
|
62
76
|
# @return [String] The user-provided type name, normalized to Ruby code
|
63
77
|
def type_ruby_name
|
64
|
-
@type_ruby_name ||= self.class.normalize_type_expression(
|
78
|
+
@type_ruby_name ||= self.class.normalize_type_expression(name, mode: :ruby)[0]
|
65
79
|
end
|
66
80
|
|
67
81
|
# @return [String] The user-provided type name, as a GraphQL name
|
68
82
|
def type_graphql_name
|
69
|
-
@type_graphql_name ||= self.class.normalize_type_expression(
|
83
|
+
@type_graphql_name ||= self.class.normalize_type_expression(name, mode: :graphql)[0]
|
70
84
|
end
|
71
85
|
|
72
86
|
# @return [String] The user-provided type name, as a file name (without extension)
|
@@ -83,6 +97,24 @@ module Graphql
|
|
83
97
|
}
|
84
98
|
end
|
85
99
|
|
100
|
+
def ruby_class_name
|
101
|
+
class_prefix =
|
102
|
+
if options[:namespaced_types]
|
103
|
+
"#{graphql_type.pluralize.camelize}::"
|
104
|
+
else
|
105
|
+
""
|
106
|
+
end
|
107
|
+
@ruby_class_name || class_prefix + type_ruby_name.sub(/^Types::/, "")
|
108
|
+
end
|
109
|
+
|
110
|
+
def subdirectory
|
111
|
+
if options[:namespaced_types]
|
112
|
+
"/#{graphql_type.pluralize}"
|
113
|
+
else
|
114
|
+
""
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
86
118
|
class NormalizedField
|
87
119
|
def initialize(name, type_expr, null)
|
88
120
|
@name = name
|
@@ -90,8 +122,12 @@ module Graphql
|
|
90
122
|
@null = null
|
91
123
|
end
|
92
124
|
|
93
|
-
def
|
94
|
-
"field :#{@name}, #{@type_expr}, null:
|
125
|
+
def to_object_field
|
126
|
+
"field :#{@name}, #{@type_expr}#{@null ? '' : ', null: false'}"
|
127
|
+
end
|
128
|
+
|
129
|
+
def to_input_argument
|
130
|
+
"argument :#{@name}, #{@type_expr}, required: false"
|
95
131
|
end
|
96
132
|
end
|
97
133
|
end
|
@@ -19,14 +19,14 @@ module Graphql
|
|
19
19
|
banner: "type type ...",
|
20
20
|
desc: "Possible types for this union (expressed as Ruby or GraphQL)"
|
21
21
|
|
22
|
-
def create_type_file
|
23
|
-
template "union.erb", "#{options[:directory]}/types/#{type_file_name}.rb"
|
24
|
-
end
|
25
|
-
|
26
22
|
private
|
27
23
|
|
24
|
+
def graphql_type
|
25
|
+
"union"
|
26
|
+
end
|
27
|
+
|
28
28
|
def normalized_possible_types
|
29
|
-
|
29
|
+
custom_fields.map { |t| self.class.normalize_type_expression(t, mode: :ruby)[0] }
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -40,12 +40,12 @@ module GraphQL
|
|
40
40
|
end
|
41
41
|
|
42
42
|
if argument.definition.type.kind.input_object?
|
43
|
-
extract_deprecated_arguments(argument.value.arguments.argument_values)
|
43
|
+
extract_deprecated_arguments(argument.value.arguments.argument_values) # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
|
44
44
|
elsif argument.definition.type.list? && !argument.value.nil?
|
45
45
|
argument
|
46
46
|
.value
|
47
47
|
.select { |value| value.respond_to?(:arguments) }
|
48
|
-
.each { |value| extract_deprecated_arguments(value.arguments.argument_values) }
|
48
|
+
.each { |value| extract_deprecated_arguments(value.arguments.argument_values) } # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
@@ -23,18 +23,22 @@ module GraphQL
|
|
23
23
|
|
24
24
|
attr_reader :field_definition, :response_path, :query
|
25
25
|
|
26
|
-
# @param
|
26
|
+
# @param parent_type [Class] The owner of `field_definition`
|
27
27
|
# @param field_definition [GraphQL::Field, GraphQL::Schema::Field] Used for getting the `.complexity` configuration
|
28
28
|
# @param query [GraphQL::Query] Used for `query.possible_types`
|
29
29
|
# @param response_path [Array<String>] The path to the response key for the field
|
30
|
-
def initialize(
|
31
|
-
@
|
30
|
+
def initialize(parent_type, field_definition, query, response_path)
|
31
|
+
@parent_type = parent_type
|
32
32
|
@field_definition = field_definition
|
33
33
|
@query = query
|
34
34
|
@response_path = response_path
|
35
35
|
@scoped_children = nil
|
36
|
+
@nodes = []
|
36
37
|
end
|
37
38
|
|
39
|
+
# @return [Array<GraphQL::Language::Nodes::Field>]
|
40
|
+
attr_reader :nodes
|
41
|
+
|
38
42
|
# Returns true if this field has no selections, ie, it's a scalar.
|
39
43
|
# We need a quick way to check whether we should continue traversing.
|
40
44
|
def terminal?
|
@@ -50,16 +54,7 @@ module GraphQL
|
|
50
54
|
end
|
51
55
|
|
52
56
|
def own_complexity(child_complexity)
|
53
|
-
|
54
|
-
case defined_complexity
|
55
|
-
when Proc
|
56
|
-
arguments = @query.arguments_for(@node, @field_definition)
|
57
|
-
defined_complexity.call(@query.context, arguments.keyword_arguments, child_complexity)
|
58
|
-
when Numeric
|
59
|
-
defined_complexity + child_complexity
|
60
|
-
else
|
61
|
-
raise("Invalid complexity: #{defined_complexity.inspect} on #{@field_definition.name}")
|
62
|
-
end
|
57
|
+
@field_definition.calculate_complexity(query: @query, nodes: @nodes, child_complexity: child_complexity)
|
63
58
|
end
|
64
59
|
end
|
65
60
|
|
@@ -79,7 +74,8 @@ module GraphQL
|
|
79
74
|
# then the query would have been rejected as invalid.
|
80
75
|
complexities_on_type = @complexities_on_type_by_query[visitor.query] ||= [ScopedTypeComplexity.new(nil, nil, query, visitor.response_path)]
|
81
76
|
|
82
|
-
complexity = complexities_on_type.last.scoped_children[parent_type][field_key] ||= ScopedTypeComplexity.new(
|
77
|
+
complexity = complexities_on_type.last.scoped_children[parent_type][field_key] ||= ScopedTypeComplexity.new(parent_type, visitor.field_definition, visitor.query, visitor.response_path)
|
78
|
+
complexity.nodes.push(node)
|
83
79
|
# Push it on the stack.
|
84
80
|
complexities_on_type.push(complexity)
|
85
81
|
end
|
@@ -100,7 +100,8 @@ module GraphQL
|
|
100
100
|
def on_field(node, parent)
|
101
101
|
@response_path.push(node.alias || node.name)
|
102
102
|
parent_type = @object_types.last
|
103
|
-
|
103
|
+
# This could be nil if the previous field wasn't found:
|
104
|
+
field_definition = parent_type && @schema.get_field(parent_type, node.name, @query.context)
|
104
105
|
@field_definitions.push(field_definition)
|
105
106
|
if !field_definition.nil?
|
106
107
|
next_object_type = field_definition.type.unwrap
|
@@ -138,14 +139,14 @@ module GraphQL
|
|
138
139
|
argument_defn = if (arg = @argument_definitions.last)
|
139
140
|
arg_type = arg.type.unwrap
|
140
141
|
if arg_type.kind.input_object?
|
141
|
-
arg_type.
|
142
|
+
arg_type.get_argument(node.name, @query.context)
|
142
143
|
else
|
143
144
|
nil
|
144
145
|
end
|
145
146
|
elsif (directive_defn = @directive_definitions.last)
|
146
|
-
directive_defn.
|
147
|
+
directive_defn.get_argument(node.name, @query.context)
|
147
148
|
elsif (field_defn = @field_definitions.last)
|
148
|
-
field_defn.
|
149
|
+
field_defn.get_argument(node.name, @query.context)
|
149
150
|
else
|
150
151
|
nil
|
151
152
|
end
|
data/lib/graphql/argument.rb
CHANGED
@@ -3,7 +3,7 @@ module GraphQL
|
|
3
3
|
# @api deprecated
|
4
4
|
class Argument
|
5
5
|
include GraphQL::Define::InstanceDefinable
|
6
|
-
|
6
|
+
deprecated_accepts_definitions :name, :type, :description, :default_value, :as, :prepare, :method_access, :deprecation_reason
|
7
7
|
attr_reader :default_value
|
8
8
|
attr_accessor :description, :name, :as, :deprecation_reason
|
9
9
|
attr_accessor :ast_node
|
@@ -89,7 +89,7 @@ module GraphQL
|
|
89
89
|
"#{context_entry.ast_node ? context_entry.ast_node.position.join(":") : ""}",
|
90
90
|
"#{context_entry.field.path}#{field_alias ? " as #{field_alias}" : ""}",
|
91
91
|
"#{context_entry.object.object.inspect}",
|
92
|
-
context_entry.arguments.to_h.inspect,
|
92
|
+
context_entry.arguments.to_h.inspect, # rubocop:disable Development/ContextIsPassedCop -- unrelated method
|
93
93
|
Backtrace::InspectResult.inspect_result(value),
|
94
94
|
]
|
95
95
|
if (parent = context_entry.parent_frame)
|
data/lib/graphql/base_type.rb
CHANGED
@@ -8,7 +8,7 @@ module GraphQL
|
|
8
8
|
include GraphQL::Define::InstanceDefinable
|
9
9
|
include GraphQL::Relay::TypeExtensions
|
10
10
|
|
11
|
-
|
11
|
+
deprecated_accepts_definitions :name, :description,
|
12
12
|
:introspection,
|
13
13
|
:default_scalar,
|
14
14
|
:default_relay,
|
@@ -41,7 +41,9 @@ module GraphQL
|
|
41
41
|
alias :graphql_name :name
|
42
42
|
# Future-compatible alias
|
43
43
|
# @see {GraphQL::SchemaMember}
|
44
|
-
|
44
|
+
def graphql_definition(silence_deprecation_warning: false)
|
45
|
+
itself
|
46
|
+
end
|
45
47
|
|
46
48
|
def type_class
|
47
49
|
metadata[:type_class]
|
@@ -194,7 +196,7 @@ module GraphQL
|
|
194
196
|
resolve_related_type(Object.const_get(type_arg))
|
195
197
|
else
|
196
198
|
if type_arg.respond_to?(:graphql_definition)
|
197
|
-
type_arg.graphql_definition
|
199
|
+
type_arg.graphql_definition(silence_deprecation_warning: true)
|
198
200
|
else
|
199
201
|
type_arg
|
200
202
|
end
|
data/lib/graphql/boolean_type.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::BOOLEAN_TYPE = GraphQL::Types::Boolean.graphql_definition
|
2
|
+
GraphQL::BOOLEAN_TYPE = GraphQL::Types::Boolean.graphql_definition(silence_deprecation_warning: true)
|
@@ -138,8 +138,8 @@ module GraphQL
|
|
138
138
|
# @api private
|
139
139
|
def result_for(key)
|
140
140
|
if !@results.key?(key)
|
141
|
-
raise <<-ERR
|
142
|
-
|
141
|
+
raise GraphQL::InvariantError, <<-ERR
|
142
|
+
Fetching result for a key on #{self.class} that hasn't been loaded yet (#{key.inspect}, loaded: #{@results.keys})
|
143
143
|
|
144
144
|
This key should have been loaded already. This is a bug in GraphQL::Dataloader, please report it on GitHub: https://github.com/rmosolgo/graphql-ruby/issues/new.
|
145
145
|
ERR
|
data/lib/graphql/dataloader.rb
CHANGED
@@ -23,8 +23,18 @@ module GraphQL
|
|
23
23
|
# end
|
24
24
|
#
|
25
25
|
class Dataloader
|
26
|
-
|
27
|
-
|
26
|
+
class << self
|
27
|
+
attr_accessor :default_nonblocking
|
28
|
+
end
|
29
|
+
|
30
|
+
AsyncDataloader = Class.new(self) { self.default_nonblocking = true }
|
31
|
+
|
32
|
+
def self.use(schema, nonblocking: nil)
|
33
|
+
schema.dataloader_class = if nonblocking
|
34
|
+
AsyncDataloader
|
35
|
+
else
|
36
|
+
self
|
37
|
+
end
|
28
38
|
end
|
29
39
|
|
30
40
|
# Call the block with a Dataloader instance,
|
@@ -39,9 +49,16 @@ module GraphQL
|
|
39
49
|
result
|
40
50
|
end
|
41
51
|
|
42
|
-
def initialize
|
52
|
+
def initialize(nonblocking: self.class.default_nonblocking)
|
43
53
|
@source_cache = Hash.new { |h, k| h[k] = {} }
|
44
54
|
@pending_jobs = []
|
55
|
+
if !nonblocking.nil?
|
56
|
+
@nonblocking = nonblocking
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def nonblocking?
|
61
|
+
@nonblocking
|
45
62
|
end
|
46
63
|
|
47
64
|
# Get a Source instance from this dataloader, for calling `.load(...)` or `.request(...)` on.
|
@@ -50,7 +67,7 @@ module GraphQL
|
|
50
67
|
# @param batch_parameters [Array<Object>]
|
51
68
|
# @return [GraphQL::Dataloader::Source] An instance of {source_class}, initialized with `self, *batch_parameters`,
|
52
69
|
# and cached for the lifetime of this {Multiplex}.
|
53
|
-
if RUBY_VERSION < "3"
|
70
|
+
if RUBY_VERSION < "3" || RUBY_ENGINE != "ruby" # truffle-ruby wasn't doing well with the implementation below
|
54
71
|
def with(source_class, *batch_args)
|
55
72
|
batch_key = source_class.batch_key_for(*batch_args)
|
56
73
|
@source_cache[source_class][batch_key] ||= begin
|
@@ -117,6 +134,9 @@ module GraphQL
|
|
117
134
|
|
118
135
|
# @api private Move along, move along
|
119
136
|
def run
|
137
|
+
if @nonblocking && !Fiber.scheduler
|
138
|
+
raise "`nonblocking: true` requires `Fiber.scheduler`, assign one with `Fiber.set_scheduler(...)` before executing GraphQL."
|
139
|
+
end
|
120
140
|
# At a high level, the algorithm is:
|
121
141
|
#
|
122
142
|
# A) Inside Fibers, run jobs from the queue one-by-one
|
@@ -137,6 +157,8 @@ module GraphQL
|
|
137
157
|
#
|
138
158
|
pending_fibers = []
|
139
159
|
next_fibers = []
|
160
|
+
pending_source_fibers = []
|
161
|
+
next_source_fibers = []
|
140
162
|
first_pass = true
|
141
163
|
|
142
164
|
while first_pass || (f = pending_fibers.shift)
|
@@ -174,31 +196,27 @@ module GraphQL
|
|
174
196
|
# This is where an evented approach would be even better -- can we tell which
|
175
197
|
# fibers are ready to continue, and continue execution there?
|
176
198
|
#
|
177
|
-
|
178
|
-
|
179
|
-
else
|
180
|
-
nil
|
199
|
+
if (first_source_fiber = create_source_fiber)
|
200
|
+
pending_source_fibers << first_source_fiber
|
181
201
|
end
|
182
202
|
|
183
|
-
|
184
|
-
while (outer_source_fiber =
|
203
|
+
while pending_source_fibers.any?
|
204
|
+
while (outer_source_fiber = pending_source_fibers.pop)
|
185
205
|
resume(outer_source_fiber)
|
186
|
-
|
187
|
-
# If this source caused more sources to become pending, run those before running this one again:
|
188
|
-
next_source_fiber = create_source_fiber
|
189
|
-
if next_source_fiber
|
190
|
-
source_fiber_queue << next_source_fiber
|
191
|
-
end
|
192
|
-
|
193
206
|
if outer_source_fiber.alive?
|
194
|
-
|
207
|
+
next_source_fibers << outer_source_fiber
|
208
|
+
end
|
209
|
+
if (next_source_fiber = create_source_fiber)
|
210
|
+
pending_source_fibers << next_source_fiber
|
195
211
|
end
|
196
212
|
end
|
213
|
+
join_queues(pending_source_fibers, next_source_fibers)
|
214
|
+
next_source_fibers.clear
|
197
215
|
end
|
198
216
|
# Move newly-enqueued Fibers on to the list to be resumed.
|
199
217
|
# Clear out the list of next-round Fibers, so that
|
200
218
|
# any Fibers that pause can be put on it.
|
201
|
-
pending_fibers
|
219
|
+
join_queues(pending_fibers, next_fibers)
|
202
220
|
next_fibers.clear
|
203
221
|
end
|
204
222
|
end
|
@@ -213,6 +231,14 @@ module GraphQL
|
|
213
231
|
nil
|
214
232
|
end
|
215
233
|
|
234
|
+
def join_queues(previous_queue, next_queue)
|
235
|
+
if @nonblocking
|
236
|
+
Fiber.scheduler.run
|
237
|
+
next_queue.select!(&:alive?)
|
238
|
+
end
|
239
|
+
previous_queue.concat(next_queue)
|
240
|
+
end
|
241
|
+
|
216
242
|
private
|
217
243
|
|
218
244
|
# If there are pending sources, return a fiber for running them.
|
@@ -266,9 +292,16 @@ module GraphQL
|
|
266
292
|
fiber_locals[fiber_var_key] = Thread.current[fiber_var_key]
|
267
293
|
end
|
268
294
|
|
269
|
-
|
270
|
-
|
271
|
-
|
295
|
+
if @nonblocking
|
296
|
+
Fiber.new(blocking: false) do
|
297
|
+
fiber_locals.each { |k, v| Thread.current[k] = v }
|
298
|
+
yield
|
299
|
+
end
|
300
|
+
else
|
301
|
+
Fiber.new do
|
302
|
+
fiber_locals.each { |k, v| Thread.current[k] = v }
|
303
|
+
yield
|
304
|
+
end
|
272
305
|
end
|
273
306
|
end
|
274
307
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
# This error is raised when `Types::ISO8601Date` is asked to return a value
|
4
|
+
# that cannot be parsed to a Ruby Date.
|
5
|
+
#
|
6
|
+
# @see GraphQL::Types::ISO8601Date which raises this error
|
7
|
+
class DateEncodingError < GraphQL::RuntimeTypeError
|
8
|
+
# The value which couldn't be encoded
|
9
|
+
attr_reader :date_value
|
10
|
+
|
11
|
+
def initialize(value)
|
12
|
+
@date_value = value
|
13
|
+
super("Date cannot be parsed: #{value}. \nDate must be be able to be parsed as a Ruby Date object.")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -167,6 +167,21 @@ ERR
|
|
167
167
|
# Each symbol in `accepts` will be assigned with `{key}=`.
|
168
168
|
# The last entry in accepts may be a hash of name-proc pairs for custom definitions.
|
169
169
|
def accepts_definitions(*accepts)
|
170
|
+
deprecated_caller = caller(0, 1).first
|
171
|
+
if deprecated_caller.include?("lib/graphql")
|
172
|
+
deprecated_caller = caller(2, 10).find { |c| !c.include?("lib/graphql") }
|
173
|
+
end
|
174
|
+
|
175
|
+
if deprecated_caller
|
176
|
+
GraphQL::Deprecation.warn <<-ERR
|
177
|
+
#{self}.accepts_definitions will be removed in GraphQL-Ruby 2.0; use a class-based definition instead. See https://graphql-ruby.org/schema/class_based_api.html.
|
178
|
+
-> called from #{deprecated_caller}
|
179
|
+
ERR
|
180
|
+
end
|
181
|
+
deprecated_accepts_definitions(*accepts)
|
182
|
+
end
|
183
|
+
|
184
|
+
def deprecated_accepts_definitions(*accepts)
|
170
185
|
new_assignments = if accepts.last.is_a?(Hash)
|
171
186
|
accepts.pop.dup
|
172
187
|
else
|
@@ -1,2 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::Directive::DeprecatedDirective = GraphQL::Schema::Directive::Deprecated.graphql_definition
|
2
|
+
GraphQL::Directive::DeprecatedDirective = GraphQL::Schema::Directive::Deprecated.graphql_definition(silence_deprecation_warning: true)
|
@@ -1,2 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::Directive::IncludeDirective = GraphQL::Schema::Directive::Include.graphql_definition
|
2
|
+
GraphQL::Directive::IncludeDirective = GraphQL::Schema::Directive::Include.graphql_definition(silence_deprecation_warning: true)
|
@@ -1,2 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::Directive::SkipDirective = GraphQL::Schema::Directive::Skip.graphql_definition
|
2
|
+
GraphQL::Directive::SkipDirective = GraphQL::Schema::Directive::Skip.graphql_definition(silence_deprecation_warning: true)
|
data/lib/graphql/directive.rb
CHANGED
@@ -8,7 +8,7 @@ module GraphQL
|
|
8
8
|
#
|
9
9
|
class Directive
|
10
10
|
include GraphQL::Define::InstanceDefinable
|
11
|
-
|
11
|
+
deprecated_accepts_definitions :locations, :name, :description, :arguments, :default_directive, argument: GraphQL::Define::AssignArgument
|
12
12
|
|
13
13
|
attr_accessor :locations, :arguments, :name, :description, :arguments_class
|
14
14
|
attr_accessor :ast_node
|
@@ -105,7 +105,3 @@ module GraphQL
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
end
|
108
|
-
|
109
|
-
require "graphql/directive/include_directive"
|
110
|
-
require "graphql/directive/skip_directive"
|
111
|
-
require "graphql/directive/deprecated_directive"
|
data/lib/graphql/enum_type.rb
CHANGED
@@ -4,7 +4,7 @@ module GraphQL
|
|
4
4
|
class EnumType < GraphQL::BaseType
|
5
5
|
extend Define::InstanceDefinable::DeprecatedDefine
|
6
6
|
|
7
|
-
|
7
|
+
deprecated_accepts_definitions :values, value: GraphQL::Define::AssignEnumValue
|
8
8
|
ensure_defined(:values, :validate_non_null_input, :coerce_non_null_input, :coerce_result)
|
9
9
|
attr_accessor :ast_node
|
10
10
|
|
@@ -34,10 +34,14 @@ module GraphQL
|
|
34
34
|
end
|
35
35
|
|
36
36
|
# @return [Hash<String => EnumValue>] `{name => value}` pairs contained in this type
|
37
|
-
def values
|
37
|
+
def values(_context = nil)
|
38
38
|
@values_by_name
|
39
39
|
end
|
40
40
|
|
41
|
+
def enum_values(_context = nil)
|
42
|
+
values.values
|
43
|
+
end
|
44
|
+
|
41
45
|
def kind
|
42
46
|
GraphQL::TypeKinds::ENUM
|
43
47
|
end
|
@@ -68,7 +72,7 @@ module GraphQL
|
|
68
72
|
class EnumValue
|
69
73
|
include GraphQL::Define::InstanceDefinable
|
70
74
|
ATTRIBUTES = [:name, :description, :deprecation_reason, :value]
|
71
|
-
|
75
|
+
deprecated_accepts_definitions(*ATTRIBUTES)
|
72
76
|
attr_accessor(*ATTRIBUTES)
|
73
77
|
attr_accessor :ast_node
|
74
78
|
ensure_defined(*ATTRIBUTES)
|
@@ -111,6 +111,7 @@ module GraphQL
|
|
111
111
|
runtime_info = ctx.namespace(:interpreter) || {}
|
112
112
|
obj = runtime_info[:current_object]
|
113
113
|
args = runtime_info[:current_arguments]
|
114
|
+
args = args && args.keyword_arguments
|
114
115
|
field = runtime_info[:current_field]
|
115
116
|
if obj.is_a?(GraphQL::Schema::Object)
|
116
117
|
obj = obj.object
|
@@ -59,7 +59,7 @@ module GraphQL
|
|
59
59
|
@empty
|
60
60
|
end
|
61
61
|
|
62
|
-
def_delegators :keyword_arguments, :key?, :[], :fetch, :keys, :each, :values
|
62
|
+
def_delegators :keyword_arguments, :key?, :[], :fetch, :keys, :each, :values, :size, :to_h
|
63
63
|
def_delegators :argument_values, :each_value
|
64
64
|
|
65
65
|
def inspect
|
@@ -31,8 +31,10 @@ module GraphQL
|
|
31
31
|
# If any jobs were enqueued, run them now,
|
32
32
|
# since this might have been called outside of execution.
|
33
33
|
# (The jobs are responsible for updating `result` in-place.)
|
34
|
-
|
35
|
-
@
|
34
|
+
if !@storage.key?(ast_node) || !@storage[ast_node].key?(argument_owner)
|
35
|
+
@dataloader.run_isolated do
|
36
|
+
@storage[ast_node][argument_owner][parent_object]
|
37
|
+
end
|
36
38
|
end
|
37
39
|
# Ack, the _hash_ is updated, but the key is eventually
|
38
40
|
# overridden with an immutable arguments instance.
|
@@ -71,11 +73,11 @@ module GraphQL
|
|
71
73
|
when Array
|
72
74
|
ast_arg_or_hash_or_value.map { |v| prepare_args_hash(query, v) }
|
73
75
|
when GraphQL::Language::Nodes::Field, GraphQL::Language::Nodes::InputObject, GraphQL::Language::Nodes::Directive
|
74
|
-
if ast_arg_or_hash_or_value.arguments.empty?
|
76
|
+
if ast_arg_or_hash_or_value.arguments.empty? # rubocop:disable Development/ContextIsPassedCop -- AST-related
|
75
77
|
return NO_ARGUMENTS
|
76
78
|
end
|
77
79
|
args_hash = {}
|
78
|
-
ast_arg_or_hash_or_value.arguments.each do |arg|
|
80
|
+
ast_arg_or_hash_or_value.arguments.each do |arg| # rubocop:disable Development/ContextIsPassedCop -- AST-related
|
79
81
|
v = prepare_args_hash(query, arg.value)
|
80
82
|
if v != NO_VALUE_GIVEN
|
81
83
|
args_hash[arg.name] = v
|