graphql 1.9.17 → 1.10.0

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.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/templates/schema.erb +7 -0
  3. data/lib/graphql/analysis/ast/field_usage.rb +1 -1
  4. data/lib/graphql/analysis/ast/visitor.rb +3 -3
  5. data/lib/graphql/analysis/ast.rb +12 -11
  6. data/lib/graphql/argument.rb +7 -35
  7. data/lib/graphql/backtrace/table.rb +10 -2
  8. data/lib/graphql/base_type.rb +4 -0
  9. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +5 -9
  10. data/lib/graphql/define/assign_enum_value.rb +1 -1
  11. data/lib/graphql/define/assign_object_field.rb +3 -3
  12. data/lib/graphql/define/defined_object_proxy.rb +8 -2
  13. data/lib/graphql/define/instance_definable.rb +10 -106
  14. data/lib/graphql/directive/deprecated_directive.rb +1 -12
  15. data/lib/graphql/directive.rb +4 -1
  16. data/lib/graphql/enum_type.rb +5 -71
  17. data/lib/graphql/execution/directive_checks.rb +2 -2
  18. data/lib/graphql/execution/errors.rb +2 -3
  19. data/lib/graphql/execution/execute.rb +1 -1
  20. data/lib/graphql/execution/interpreter/runtime.rb +106 -55
  21. data/lib/graphql/execution/interpreter.rb +5 -11
  22. data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
  23. data/lib/graphql/execution/lookahead.rb +5 -5
  24. data/lib/graphql/execution/multiplex.rb +13 -3
  25. data/lib/graphql/field.rb +9 -117
  26. data/lib/graphql/filter.rb +1 -1
  27. data/lib/graphql/function.rb +1 -30
  28. data/lib/graphql/input_object_type.rb +2 -24
  29. data/lib/graphql/interface_type.rb +2 -23
  30. data/lib/graphql/introspection/base_object.rb +2 -5
  31. data/lib/graphql/introspection/directive_type.rb +1 -1
  32. data/lib/graphql/introspection/entry_points.rb +7 -7
  33. data/lib/graphql/introspection/input_value_type.rb +27 -9
  34. data/lib/graphql/introspection/schema_type.rb +1 -6
  35. data/lib/graphql/introspection/type_type.rb +5 -5
  36. data/lib/graphql/language/definition_slice.rb +21 -10
  37. data/lib/graphql/language/document_from_schema_definition.rb +50 -44
  38. data/lib/graphql/language/nodes.rb +3 -3
  39. data/lib/graphql/language/parser.rb +644 -646
  40. data/lib/graphql/language/parser.y +6 -4
  41. data/lib/graphql/language.rb +1 -1
  42. data/lib/graphql/non_null_type.rb +0 -10
  43. data/lib/graphql/object_type.rb +1 -21
  44. data/lib/graphql/pagination/active_record_relation_connection.rb +35 -0
  45. data/lib/graphql/pagination/array_connection.rb +77 -0
  46. data/lib/graphql/pagination/connection.rb +171 -0
  47. data/lib/graphql/pagination/connections.rb +108 -0
  48. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  49. data/lib/graphql/pagination/relation_connection.rb +151 -0
  50. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  51. data/lib/graphql/pagination.rb +6 -0
  52. data/lib/graphql/query/arguments.rb +2 -1
  53. data/lib/graphql/query/context.rb +2 -5
  54. data/lib/graphql/query/literal_input.rb +30 -10
  55. data/lib/graphql/query/variable_validation_error.rb +1 -1
  56. data/lib/graphql/query/variables.rb +7 -3
  57. data/lib/graphql/query.rb +9 -5
  58. data/lib/graphql/relay/base_connection.rb +4 -0
  59. data/lib/graphql/relay/connection_type.rb +2 -1
  60. data/lib/graphql/relay/edge_type.rb +1 -0
  61. data/lib/graphql/relay/edges_instrumentation.rb +1 -1
  62. data/lib/graphql/relay/mutation.rb +1 -86
  63. data/lib/graphql/relay/node.rb +2 -2
  64. data/lib/graphql/scalar_type.rb +1 -58
  65. data/lib/graphql/schema/argument.rb +51 -6
  66. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
  67. data/lib/graphql/schema/build_from_definition/resolve_map.rb +10 -4
  68. data/lib/graphql/schema/build_from_definition.rb +167 -178
  69. data/lib/graphql/schema/built_in_types.rb +5 -5
  70. data/lib/graphql/schema/directive/deprecated.rb +18 -0
  71. data/lib/graphql/schema/directive.rb +28 -2
  72. data/lib/graphql/schema/enum.rb +40 -3
  73. data/lib/graphql/schema/enum_value.rb +5 -1
  74. data/lib/graphql/schema/field/connection_extension.rb +11 -1
  75. data/lib/graphql/schema/field.rb +59 -31
  76. data/lib/graphql/schema/find_inherited_value.rb +13 -0
  77. data/lib/graphql/schema/finder.rb +13 -11
  78. data/lib/graphql/schema/input_object.rb +107 -2
  79. data/lib/graphql/schema/interface.rb +10 -7
  80. data/lib/graphql/schema/introspection_system.rb +108 -37
  81. data/lib/graphql/schema/late_bound_type.rb +1 -0
  82. data/lib/graphql/schema/list.rb +41 -0
  83. data/lib/graphql/schema/loader.rb +16 -4
  84. data/lib/graphql/schema/member/base_dsl_methods.rb +21 -11
  85. data/lib/graphql/schema/member/build_type.rb +5 -1
  86. data/lib/graphql/schema/member/cached_graphql_definition.rb +5 -0
  87. data/lib/graphql/schema/member/has_arguments.rb +2 -2
  88. data/lib/graphql/schema/member/has_ast_node.rb +17 -0
  89. data/lib/graphql/schema/member/has_fields.rb +4 -4
  90. data/lib/graphql/schema/member/validates_input.rb +33 -0
  91. data/lib/graphql/schema/member.rb +5 -0
  92. data/lib/graphql/schema/mutation.rb +1 -1
  93. data/lib/graphql/schema/non_null.rb +25 -0
  94. data/lib/graphql/schema/object.rb +15 -5
  95. data/lib/graphql/schema/printer.rb +1 -2
  96. data/lib/graphql/schema/relay_classic_mutation.rb +1 -1
  97. data/lib/graphql/schema/resolver.rb +3 -15
  98. data/lib/graphql/schema/scalar.rb +19 -3
  99. data/lib/graphql/schema/subscription.rb +5 -5
  100. data/lib/graphql/schema/traversal.rb +1 -1
  101. data/lib/graphql/schema/type_expression.rb +21 -13
  102. data/lib/graphql/schema/type_membership.rb +2 -2
  103. data/lib/graphql/schema/union.rb +2 -3
  104. data/lib/graphql/schema/validation.rb +2 -2
  105. data/lib/graphql/schema/warden.rb +45 -20
  106. data/lib/graphql/schema.rb +764 -151
  107. data/lib/graphql/static_validation/base_visitor.rb +10 -6
  108. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +9 -4
  109. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +10 -7
  110. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
  111. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
  112. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
  113. data/lib/graphql/static_validation/rules/fields_will_merge.rb +4 -4
  114. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  115. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
  116. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -3
  117. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +5 -6
  118. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  119. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +1 -1
  120. data/lib/graphql/static_validation/type_stack.rb +2 -2
  121. data/lib/graphql/static_validation/validator.rb +1 -1
  122. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +3 -3
  123. data/lib/graphql/subscriptions/event.rb +7 -4
  124. data/lib/graphql/subscriptions/instrumentation.rb +10 -5
  125. data/lib/graphql/subscriptions/subscription_root.rb +0 -1
  126. data/lib/graphql/subscriptions.rb +34 -9
  127. data/lib/graphql/tracing/active_support_notifications_tracing.rb +14 -10
  128. data/lib/graphql/tracing/appsignal_tracing.rb +8 -0
  129. data/lib/graphql/tracing/data_dog_tracing.rb +8 -0
  130. data/lib/graphql/tracing/new_relic_tracing.rb +8 -0
  131. data/lib/graphql/tracing/platform_tracing.rb +26 -6
  132. data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
  133. data/lib/graphql/tracing/scout_tracing.rb +8 -0
  134. data/lib/graphql/tracing/skylight_tracing.rb +8 -0
  135. data/lib/graphql/tracing.rb +7 -3
  136. data/lib/graphql/types/int.rb +1 -1
  137. data/lib/graphql/types/relay/base_connection.rb +3 -1
  138. data/lib/graphql/union_type.rb +13 -28
  139. data/lib/graphql/unresolved_type_error.rb +2 -2
  140. data/lib/graphql/version.rb +1 -1
  141. data/lib/graphql.rb +2 -1
  142. metadata +15 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0486697e594e11affbd5f7d0a661023e2a649abfa654e8faa26b5849fce0b473'
4
- data.tar.gz: 3943f0dcdeb83dc593ddf675cee9143180d61ea25f454ac1ba6e8f098f4bfaf3
3
+ metadata.gz: 5410e491e639ee266d3c13a8f3073be2d8270289548f6c63e10a056fe5ff8a43
4
+ data.tar.gz: 9b6a6a7dd62e3946b49b0e46c8dbf7745feeb4b48cb931b9d9d2deb9221bb43a
5
5
  SHA512:
6
- metadata.gz: 5075b2a02ca5dc3d219736b64b768ef6bbb46f09cebb92aac5ab5d3249b4675b229cb058fe44a328543328497f91658078919e04019857802f42e219585d11fa
7
- data.tar.gz: 8236278511482220a05461616be330b7c629241f2cb092b67392412d4710c6f5ab2c8e75d342c598bb64bec0fa02b003972d9b1af971562ccaf765daac444492
6
+ metadata.gz: 78f06f66e32517103a861c2adeeeac0f090dbb111d4827a22f3f7a398b8825b10fc1d89bfcc96be3543e8c043351a7023ef1542284bc5ce60518ed5eeb6e6c70
7
+ data.tar.gz: 53264646f1a059b97494503b350de5908d2ca70392c749426d6863275ac4b99f4629dbf18ae21fc21f1bd85fbb02ad4f7f17b7a8ce54a64e0aa89ee6bbee253b
@@ -1,4 +1,11 @@
1
1
  class <%= schema_name %> < GraphQL::Schema
2
+ query(Types::QueryType)
3
+
4
+ # Opt in to the new runtime (default in future graphql-ruby versions)
5
+ use GraphQL::Execution::Interpreter
6
+
7
+ # Add built-in connections for pagination
8
+ use GraphQL::Pagination::Connections
2
9
  <% if options[:relay] %>
3
10
  # Relay Object Identification:
4
11
 
@@ -11,7 +11,7 @@ module GraphQL
11
11
 
12
12
  def on_leave_field(node, parent, visitor)
13
13
  field_defn = visitor.field_definition
14
- field = "#{visitor.parent_type_definition.name}.#{field_defn.name}"
14
+ field = "#{visitor.parent_type_definition.graphql_name}.#{field_defn.graphql_name}"
15
15
  @used_fields << field
16
16
  @used_deprecated_fields << field if field_defn.deprecation_reason
17
17
  end
@@ -134,7 +134,7 @@ module GraphQL
134
134
  argument_defn = if (arg = @argument_definitions.last)
135
135
  arg_type = arg.type.unwrap
136
136
  if arg_type.kind.input_object?
137
- arg_type.input_fields[node.name]
137
+ arg_type.arguments[node.name]
138
138
  else
139
139
  nil
140
140
  end
@@ -214,7 +214,7 @@ module GraphQL
214
214
  fragment_def = query.fragments[fragment_spread.name]
215
215
 
216
216
  object_type = if fragment_def.type
217
- query.schema.types.fetch(fragment_def.type.name, nil)
217
+ @query.warden.get_type(fragment_def.type.name)
218
218
  else
219
219
  object_types.last
220
220
  end
@@ -245,7 +245,7 @@ module GraphQL
245
245
 
246
246
  def on_fragment_with_type(node)
247
247
  object_type = if node.type
248
- @schema.types.fetch(node.type.name, nil)
248
+ @query.warden.get_type(node.type.name)
249
249
  else
250
250
  @object_types.last
251
251
  end
@@ -12,9 +12,8 @@ module GraphQL
12
12
  module AST
13
13
  module_function
14
14
 
15
- def use(schema_defn)
16
- schema = schema_defn.target
17
- schema.analysis_engine = GraphQL::Analysis::AST
15
+ def use(schema_class)
16
+ schema_class.analysis_engine = GraphQL::Analysis::AST
18
17
  end
19
18
 
20
19
  # Analyze a multiplex, and all queries within.
@@ -60,16 +59,18 @@ module GraphQL
60
59
  .select { |analyzer| analyzer.analyze? }
61
60
 
62
61
  analyzers_to_run = query_analyzers + multiplex_analyzers
63
- return [] unless analyzers_to_run.any?
62
+ if analyzers_to_run.any?
63
+ visitor = GraphQL::Analysis::AST::Visitor.new(
64
+ query: query,
65
+ analyzers: analyzers_to_run
66
+ )
64
67
 
65
- visitor = GraphQL::Analysis::AST::Visitor.new(
66
- query: query,
67
- analyzers: analyzers_to_run
68
- )
68
+ visitor.visit
69
69
 
70
- visitor.visit
71
-
72
- query_analyzers.map(&:result)
70
+ query_analyzers.map(&:result)
71
+ else
72
+ []
73
+ end
73
74
  end
74
75
  end
75
76
 
@@ -1,38 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- # Used for defined arguments ({Field}, {InputObjectType})
4
- #
5
- # {#name} must be a String.
6
- #
7
- # @example defining an argument for a field
8
- # GraphQL::Field.define do
9
- # # ...
10
- # argument :favoriteFood, types.String, "Favorite thing to eat", default_value: "pizza"
11
- # end
12
- #
13
- # @example defining an argument for an {InputObjectType}
14
- # GraphQL::InputObjectType.define do
15
- # argument :newName, !types.String
16
- # end
17
- #
18
- # @example defining an argument with a `prepare` function
19
- # GraphQL::Field.define do
20
- # argument :userId, types.ID, prepare: ->(userId) do
21
- # User.find_by(id: userId)
22
- # end
23
- # end
24
- #
25
- # @example returning an {ExecutionError} from a `prepare` function
26
- # GraphQL::Field.define do
27
- # argument :date do
28
- # type !types.String
29
- # prepare ->(date) do
30
- # return GraphQL::ExecutionError.new("Invalid date format") unless DateValidator.valid?(date)
31
- # Time.zone.parse(date)
32
- # end
33
- # end
34
- # end
35
-
3
+ # @api deprecated
36
4
  class Argument
37
5
  include GraphQL::Define::InstanceDefinable
38
6
  accepts_definitions :name, :type, :description, :default_value, :as, :prepare, :method_access
@@ -113,6 +81,10 @@ module GraphQL
113
81
  @prepare_proc = BackwardsCompatibility.wrap_arity(prepare_proc, from: 1, to: 2, name: "Argument#prepare(value, ctx)")
114
82
  end
115
83
 
84
+ def type_class
85
+ metadata[:type_class]
86
+ end
87
+
116
88
  NO_DEFAULT_VALUE = Object.new
117
89
  # @api private
118
90
  def self.from_dsl(name, type_or_argument = nil, description = nil, default_value: NO_DEFAULT_VALUE, as: nil, prepare: DefaultPrepare, **kwargs, &block)
@@ -134,9 +106,9 @@ module GraphQL
134
106
  end
135
107
 
136
108
  if type_or_argument.is_a?(GraphQL::Argument)
137
- type_or_argument.redefine(kwargs, &block)
109
+ type_or_argument.redefine(**kwargs, &block)
138
110
  else
139
- GraphQL::Argument.define(kwargs, &block)
111
+ GraphQL::Argument.define(**kwargs, &block)
140
112
  end
141
113
  end
142
114
 
@@ -84,10 +84,14 @@ module GraphQL
84
84
  field_name = "#{ctx.irep_node.owner_type.name}.#{ctx.field.name}"
85
85
  position = "#{ctx.ast_node.line}:#{ctx.ast_node.col}"
86
86
  field_alias = ctx.ast_node.alias
87
+ object = ctx.object
88
+ if object.is_a?(GraphQL::Schema::Object)
89
+ object = object.object
90
+ end
87
91
  rows << [
88
92
  "#{position}",
89
93
  "#{field_name}#{field_alias ? " as #{field_alias}" : ""}",
90
- "#{ctx.object.inspect}",
94
+ "#{object.inspect}",
91
95
  ctx.irep_node.arguments.to_h.inspect,
92
96
  Backtrace::InspectResult.inspect_result(top && @override_value ? @override_value : ctx.value),
93
97
  ]
@@ -104,10 +108,14 @@ module GraphQL
104
108
  position = "?:?"
105
109
  end
106
110
  op_name = query.selected_operation_name
111
+ object = query.root_value
112
+ if object.is_a?(GraphQL::Schema::Object)
113
+ object = object.object
114
+ end
107
115
  rows << [
108
116
  "#{position}",
109
117
  "#{op_type}#{op_name ? " #{op_name}" : ""}",
110
- "#{query.root_value.inspect}",
118
+ "#{object.inspect}",
111
119
  query.variables.to_h.inspect,
112
120
  Backtrace::InspectResult.inspect_result(query.context.value),
113
121
  ]
@@ -43,6 +43,10 @@ module GraphQL
43
43
  # @see {GraphQL::SchemaMember}
44
44
  alias :graphql_definition :itself
45
45
 
46
+ def type_class
47
+ metadata[:type_class]
48
+ end
49
+
46
50
  def name=(name)
47
51
  GraphQL::NameValidator.validate!(name)
48
52
  @name = name
@@ -70,15 +70,11 @@ module GraphQL
70
70
  ")
71
71
  end
72
72
 
73
- def assert_empty_document(query_string)
74
- doc = parse(query_string)
75
- assert_equal 0, doc.definitions.length
76
- end
77
-
78
- def test_it_parses_blank_queries
79
- assert_empty_document("")
80
- assert_empty_document(" ")
81
- assert_empty_document("\t \t")
73
+ def test_it_rejects_blank_queries
74
+ assert_raises_parse_error("")
75
+ assert_raises_parse_error(" ")
76
+ assert_raises_parse_error("\t \t")
77
+ assert_raises_parse_error(" # comment ")
82
78
  end
83
79
 
84
80
  def test_it_restricts_on
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
3
  module Define
4
- # Turn enum value configs into a {GraphQL::EnumType::EnumValue} and register it with the {GraphQL::EnumType}
4
+ # @api deprecated
5
5
  module AssignEnumValue
6
6
  def self.call(enum_type, name, desc = nil, deprecation_reason: nil, value: name, &block)
7
7
  enum_value = GraphQL::EnumType::EnumValue.define(
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
3
  module Define
4
- # Turn field configs into a {GraphQL::Field} and attach it to a {GraphQL::ObjectType} or {GraphQL::InterfaceType}
4
+ # @api deprecated
5
5
  module AssignObjectField
6
6
  def self.call(owner_type, name, type_or_field = nil, desc = nil, function: nil, field: nil, relay_mutation_function: nil, **kwargs, &block)
7
7
  name_s = name.to_s
@@ -28,9 +28,9 @@ module GraphQL
28
28
  end
29
29
 
30
30
  obj_field = if base_field
31
- base_field.redefine(kwargs, &block)
31
+ base_field.redefine(**kwargs, &block)
32
32
  else
33
- GraphQL::Field.define(kwargs, &block)
33
+ GraphQL::Field.define(**kwargs, &block)
34
34
  end
35
35
 
36
36
 
@@ -32,10 +32,16 @@ module GraphQL
32
32
  end
33
33
 
34
34
  # Lookup a function from the dictionary and call it if it's found.
35
- def method_missing(name, *args, &block)
35
+ def method_missing(name, *args, **kwargs, &block)
36
36
  definition = @dictionary[name]
37
37
  if definition
38
- definition.call(@target, *args, &block)
38
+ # Avoid passing `kwargs` when it's not used.
39
+ # Ruby 2.7 does fine here, but older Rubies receive too many arguments.
40
+ if kwargs.any?
41
+ definition.call(@target, *args, **kwargs, &block)
42
+ else
43
+ definition.call(@target, *args, &block)
44
+ end
39
45
  else
40
46
  msg = "#{@target.class.name} can't define '#{name}'"
41
47
  raise NoDefinitionError, msg, caller
@@ -1,118 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
3
  module Define
4
- # This module provides the `.define { ... }` API for
5
- # {GraphQL::BaseType}, {GraphQL::Field} and others.
6
- #
7
- # Calling `.accepts_definitions(...)` creates:
8
- #
9
- # - a keyword to the `.define` method
10
- # - a helper method in the `.define { ... }` block
11
- #
12
- # The `.define { ... }` block will be called lazily. To be sure it has been
13
- # called, use the private method `#ensure_defined`. That will call the
14
- # definition block if it hasn't been called already.
15
- #
16
- # The goals are:
17
- #
18
- # - Minimal overhead in consuming classes
19
- # - Independence between consuming classes
20
- # - Extendable by third-party libraries without monkey-patching or other nastiness
21
- #
22
- # @example Make a class definable
23
- # class Car
24
- # include GraphQL::Define::InstanceDefinable
25
- # attr_accessor :make, :model, :doors
26
- # accepts_definitions(
27
- # # These attrs will be defined with plain setters, `{attr}=`
28
- # :make, :model,
29
- # # This attr has a custom definition which applies the config to the target
30
- # doors: ->(car, doors_count) { doors_count.times { car.doors << Door.new } }
31
- # )
32
- # ensure_defined(:make, :model, :doors)
33
- #
34
- # def initialize
35
- # @doors = []
36
- # end
37
- # end
38
- #
39
- # class Door; end;
40
- #
41
- # # Create an instance with `.define`:
42
- # subaru_baja = Car.define do
43
- # make "Subaru"
44
- # model "Baja"
45
- # doors 4
46
- # end
47
- #
48
- # # The custom proc was applied:
49
- # subaru_baja.doors #=> [<Door>, <Door>, <Door>, <Door>]
50
- #
51
- # @example Extending the definition of a class
52
- # # Add some definitions:
53
- # Car.accepts_definitions(all_wheel_drive: GraphQL::Define.assign_metadata_key(:all_wheel_drive))
54
- #
55
- # # Use it in a definition
56
- # subaru_baja = Car.define do
57
- # # ...
58
- # all_wheel_drive true
59
- # end
60
- #
61
- # # Access it from metadata
62
- # subaru_baja.metadata[:all_wheel_drive] # => true
63
- #
64
- # @example Extending the definition of a class via a plugin
65
- # # A plugin is any object that responds to `.use(definition)`
66
- # module SubaruCar
67
- # extend self
68
- #
69
- # def use(defn)
70
- # # `defn` has the same methods as within `.define { ... }` block
71
- # defn.make "Subaru"
72
- # defn.doors 4
73
- # end
74
- # end
75
- #
76
- # # Use the plugin within a `.define { ... }` block
77
- # subaru_baja = Car.define do
78
- # use SubaruCar
79
- # model 'Baja'
80
- # end
81
- #
82
- # subaru_baja.make # => "Subaru"
83
- # subaru_baja.doors # => [<Door>, <Door>, <Door>, <Door>]
84
- #
85
- # @example Making a copy with an extended definition
86
- # # Create an instance with `.define`:
87
- # subaru_baja = Car.define do
88
- # make "Subaru"
89
- # model "Baja"
90
- # doors 4
91
- # end
92
- #
93
- # # Then extend it with `#redefine`
94
- # two_door_baja = subaru_baja.redefine do
95
- # doors 2
96
- # end
4
+ # @api deprecated
97
5
  module InstanceDefinable
98
6
  def self.included(base)
99
7
  base.extend(ClassMethods)
100
8
  base.ensure_defined(:metadata)
101
9
  end
102
10
 
103
- # `metadata` can store arbitrary key-values with an object.
104
- #
105
- # @return [Hash<Object, Object>] Hash for user-defined storage
11
+ # @api deprecated
106
12
  def metadata
107
13
  @metadata ||= {}
108
14
  end
109
15
 
110
- # Mutate this instance using functions from its {.definition}s.
111
- # Keywords or helpers in the block correspond to keys given to `accepts_definitions`.
112
- #
113
- # Note that the block is not called right away -- instead, it's deferred until
114
- # one of the defined fields is needed.
115
- # @return [void]
16
+ # @api deprecated
116
17
  def define(**kwargs, &block)
117
18
  # make sure the previous definition_proc was executed:
118
19
  ensure_defined
@@ -121,9 +22,7 @@ module GraphQL
121
22
  nil
122
23
  end
123
24
 
124
- # Shallow-copy this object, then apply new definitions to the copy.
125
- # @see {#define} for arguments
126
- # @return [InstanceDefinable] A new instance, with any extended definitions
25
+ # @api deprecated
127
26
  def redefine(**kwargs, &block)
128
27
  ensure_defined
129
28
  new_inst = self.dup
@@ -154,7 +53,12 @@ module GraphQL
154
53
  defn_proxy = DefinedObjectProxy.new(self)
155
54
  # Apply definition from `define(...)` kwargs
156
55
  defn.define_keywords.each do |keyword, value|
157
- defn_proxy.public_send(keyword, value)
56
+ # Don't splat string hashes, which blows up on Rubies before 2.7
57
+ if value.is_a?(Hash) && value.each_key.all? { |k| k.is_a?(Symbol) }
58
+ defn_proxy.public_send(keyword, **value)
59
+ else
60
+ defn_proxy.public_send(keyword, value)
61
+ end
158
62
  end
159
63
  # and/or apply definition from `define { ... }` block
160
64
  if defn.define_proc
@@ -1,13 +1,2 @@
1
1
  # frozen_string_literal: true
2
- GraphQL::Directive::DeprecatedDirective = GraphQL::Directive.define do
3
- name "deprecated"
4
- description "Marks an element of a GraphQL schema as no longer supported."
5
- locations([GraphQL::Directive::FIELD_DEFINITION, GraphQL::Directive::ENUM_VALUE])
6
-
7
- reason_description = "Explains why this element was deprecated, usually also including a "\
8
- "suggestion for how to access supported similar data. Formatted "\
9
- "in [Markdown](https://daringfireball.net/projects/markdown/)."
10
-
11
- argument :reason, GraphQL::STRING_TYPE, reason_description, default_value: GraphQL::Directive::DEFAULT_DEPRECATION_REASON
12
- default_directive true
13
- end
2
+ GraphQL::Directive::DeprecatedDirective = GraphQL::Schema::Directive::Deprecated.graphql_definition
@@ -45,7 +45,6 @@ module GraphQL
45
45
  INPUT_FIELD_DEFINITION = :INPUT_FIELD_DEFINITION,
46
46
  ]
47
47
 
48
- DEFAULT_DEPRECATION_REASON = 'No longer supported'
49
48
  LOCATION_DESCRIPTIONS = {
50
49
  QUERY: 'Location adjacent to a query operation.',
51
50
  MUTATION: 'Location adjacent to a mutation operation.',
@@ -96,6 +95,10 @@ module GraphQL
96
95
  def inspect
97
96
  "#<GraphQL::Directive #{name}>"
98
97
  end
98
+
99
+ def type_class
100
+ metadata[:type_class]
101
+ end
99
102
  end
100
103
  end
101
104
 
@@ -1,76 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- # Represents a collection of related values.
4
- # By convention, enum names are `SCREAMING_CASE_NAMES`,
5
- # but other identifiers are supported too.
6
- #
7
- # You can use as return types _or_ as inputs.
8
- #
9
- # By default, enums are passed to `resolve` functions as
10
- # the strings that identify them, but you can provide a
11
- # custom Ruby value with the `value:` keyword.
12
- #
13
- # @example An enum of programming languages
14
- # LanguageEnum = GraphQL::EnumType.define do
15
- # name "Language"
16
- # description "Programming language for Web projects"
17
- # value("PYTHON", "A dynamic, function-oriented language")
18
- # value("RUBY", "A very dynamic language aimed at programmer happiness")
19
- # value("JAVASCRIPT", "Accidental lingua franca of the web")
20
- # end
21
- #
22
- # @example Using an enum as a return type
23
- # field :favoriteLanguage, LanguageEnum, "This person's favorite coding language"
24
- # # ...
25
- # # In a query:
26
- # Schema.execute("{ coder(id: 1) { favoriteLanguage } }")
27
- # # { "data" => { "coder" => { "favoriteLanguage" => "RUBY" } } }
28
- #
29
- # @example Defining an enum input
30
- # field :coders, types[CoderType] do
31
- # argument :knowing, types[LanguageEnum]
32
- # resolve ->(obj, args, ctx) {
33
- # Coder.where(language: args[:knowing])
34
- # }
35
- # end
36
- #
37
- # @example Using an enum as input
38
- # {
39
- # # find coders who know Python and Ruby
40
- # coders(knowing: [PYTHON, RUBY]) {
41
- # name
42
- # hourlyRate
43
- # }
44
- # }
45
- #
46
- # @example Enum whose values are different in Ruby-land
47
- # GraphQL::EnumType.define do
48
- # # ...
49
- # # use the `value:` keyword:
50
- # value("RUBY", "Lisp? Smalltalk?", value: :rb)
51
- # end
52
- #
53
- # # Now, resolve functions will receive `:rb` instead of `"RUBY"`
54
- # field :favoriteLanguage, LanguageEnum
55
- # resolve ->(obj, args, ctx) {
56
- # args[:favoriteLanguage] # => :rb
57
- # }
58
- #
59
- # @example Enum whose values are different in ActiveRecord-land
60
- # class Language < ActiveRecord::Base
61
- # enum language: {
62
- # rb: 0
63
- # }
64
- # end
65
- #
66
- # # Now enum type should be defined as
67
- # GraphQL::EnumType.define do
68
- # # ...
69
- # # use the `value:` keyword:
70
- # value("RUBY", "Lisp? Smalltalk?", value: 'rb')
71
- # end
72
- #
73
-
3
+ # @api deprecated
74
4
  class EnumType < GraphQL::BaseType
75
5
  accepts_definitions :values, value: GraphQL::Define::AssignEnumValue
76
6
  ensure_defined(:values, :validate_non_null_input, :coerce_non_null_input, :coerce_result)
@@ -151,6 +81,10 @@ module GraphQL
151
81
  def graphql_name
152
82
  name
153
83
  end
84
+
85
+ def type_class
86
+ metadata[:type_class]
87
+ end
154
88
  end
155
89
 
156
90
  class UnresolvedValueError < GraphQL::Error
@@ -18,12 +18,12 @@ module GraphQL
18
18
  case name
19
19
  when SKIP
20
20
  args = query.arguments_for(directive_ast_node, directive_defn)
21
- if args['if'] == true
21
+ if args[:if] == true
22
22
  return false
23
23
  end
24
24
  when INCLUDE
25
25
  args = query.arguments_for(directive_ast_node, directive_defn)
26
- if args['if'] == false
26
+ if args[:if] == false
27
27
  return false
28
28
  end
29
29
  else
@@ -18,8 +18,7 @@ module GraphQL
18
18
  #
19
19
  class Errors
20
20
  def self.use(schema)
21
- schema_class = schema.is_a?(Class) ? schema : schema.target.class
22
- schema_class.error_handler = self.new(schema_class)
21
+ schema.error_handler = self.new(schema)
23
22
  end
24
23
 
25
24
  def initialize(schema)
@@ -41,7 +40,7 @@ module GraphQL
41
40
  def with_error_handling(ctx)
42
41
  yield
43
42
  rescue StandardError => err
44
- rescues = @schema.rescues
43
+ rescues = ctx.schema.rescues
45
44
  _err_class, handler = rescues.find { |err_class, handler| err.is_a?(err_class) }
46
45
  if handler
47
46
  runtime_info = ctx.namespace(:interpreter) || {}
@@ -20,7 +20,7 @@ module GraphQL
20
20
 
21
21
  def execute(ast_operation, root_type, query)
22
22
  result = resolve_root_selection(query)
23
- lazy_resolve_root_selection(result, {query: query})
23
+ lazy_resolve_root_selection(result, **{query: query})
24
24
  GraphQL::Execution::Flatten.call(query.context)
25
25
  end
26
26