graphql 1.9.21 → 1.10.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/core.rb +0 -1
  3. data/lib/generators/graphql/install_generator.rb +0 -1
  4. data/lib/generators/graphql/mutation_generator.rb +1 -1
  5. data/lib/generators/graphql/templates/base_field.erb +4 -0
  6. data/lib/generators/graphql/templates/graphql_controller.erb +0 -5
  7. data/lib/generators/graphql/templates/mutation.erb +1 -1
  8. data/lib/generators/graphql/templates/schema.erb +1 -1
  9. data/lib/graphql.rb +1 -11
  10. data/lib/graphql/analysis/ast.rb +2 -2
  11. data/lib/graphql/analysis/ast/analyzer.rb +4 -23
  12. data/lib/graphql/analysis/ast/max_query_complexity.rb +3 -3
  13. data/lib/graphql/analysis/ast/max_query_depth.rb +3 -7
  14. data/lib/graphql/analysis/ast/query_complexity.rb +2 -2
  15. data/lib/graphql/argument.rb +6 -2
  16. data/lib/graphql/backtrace/table.rb +10 -2
  17. data/lib/graphql/base_type.rb +5 -1
  18. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +5 -9
  19. data/lib/graphql/define/assign_object_field.rb +2 -2
  20. data/lib/graphql/define/defined_object_proxy.rb +0 -3
  21. data/lib/graphql/define/instance_definable.rb +3 -14
  22. data/lib/graphql/enum_type.rb +4 -0
  23. data/lib/graphql/execution/directive_checks.rb +2 -2
  24. data/lib/graphql/execution/errors.rb +14 -15
  25. data/lib/graphql/execution/execute.rb +1 -1
  26. data/lib/graphql/execution/interpreter/runtime.rb +17 -39
  27. data/lib/graphql/execution/multiplex.rb +3 -3
  28. data/lib/graphql/field.rb +8 -0
  29. data/lib/graphql/filter.rb +1 -1
  30. data/lib/graphql/function.rb +1 -1
  31. data/lib/graphql/input_object_type.rb +1 -2
  32. data/lib/graphql/introspection/entry_points.rb +1 -2
  33. data/lib/graphql/introspection/input_value_type.rb +27 -9
  34. data/lib/graphql/introspection/schema_type.rb +1 -2
  35. data/lib/graphql/language/block_string.rb +2 -2
  36. data/lib/graphql/language/document_from_schema_definition.rb +5 -11
  37. data/lib/graphql/language/lexer.rb +48 -49
  38. data/lib/graphql/language/lexer.rl +48 -49
  39. data/lib/graphql/language/nodes.rb +11 -14
  40. data/lib/graphql/language/parser.rb +645 -650
  41. data/lib/graphql/language/parser.y +7 -8
  42. data/lib/graphql/language/token.rb +1 -1
  43. data/lib/graphql/non_null_type.rb +0 -10
  44. data/lib/graphql/pagination.rb +6 -0
  45. data/lib/graphql/pagination/active_record_relation_connection.rb +35 -0
  46. data/lib/graphql/pagination/array_connection.rb +78 -0
  47. data/lib/graphql/pagination/connection.rb +150 -0
  48. data/lib/graphql/pagination/connections.rb +103 -0
  49. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  50. data/lib/graphql/pagination/relation_connection.rb +157 -0
  51. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  52. data/lib/graphql/query.rb +1 -7
  53. data/lib/graphql/query/arguments.rb +3 -9
  54. data/lib/graphql/query/context.rb +9 -31
  55. data/lib/graphql/query/literal_input.rb +29 -10
  56. data/lib/graphql/query/null_context.rb +0 -4
  57. data/lib/graphql/query/variable_validation_error.rb +1 -1
  58. data/lib/graphql/query/variables.rb +2 -4
  59. data/lib/graphql/relay/base_connection.rb +7 -3
  60. data/lib/graphql/relay/edges_instrumentation.rb +1 -1
  61. data/lib/graphql/relay/node.rb +2 -2
  62. data/lib/graphql/relay/relation_connection.rb +5 -9
  63. data/lib/graphql/schema.rb +27 -68
  64. data/lib/graphql/schema/argument.rb +31 -5
  65. data/lib/graphql/schema/base_64_bp.rb +2 -3
  66. data/lib/graphql/schema/build_from_definition.rb +113 -179
  67. data/lib/graphql/schema/build_from_definition/resolve_map.rb +10 -4
  68. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
  69. data/lib/graphql/schema/directive.rb +6 -7
  70. data/lib/graphql/schema/directive/feature.rb +1 -1
  71. data/lib/graphql/schema/enum.rb +1 -0
  72. data/lib/graphql/schema/enum_value.rb +4 -1
  73. data/lib/graphql/schema/field.rb +37 -39
  74. data/lib/graphql/schema/field/connection_extension.rb +11 -1
  75. data/lib/graphql/schema/input_object.rb +2 -5
  76. data/lib/graphql/schema/interface.rb +2 -0
  77. data/lib/graphql/schema/introspection_system.rb +1 -4
  78. data/lib/graphql/schema/loader.rb +6 -12
  79. data/lib/graphql/schema/member.rb +2 -0
  80. data/lib/graphql/schema/member/base_dsl_methods.rb +2 -2
  81. data/lib/graphql/schema/member/build_type.rb +4 -0
  82. data/lib/graphql/schema/member/cached_graphql_definition.rb +5 -0
  83. data/lib/graphql/schema/member/has_ast_node.rb +17 -0
  84. data/lib/graphql/schema/member/has_fields.rb +10 -16
  85. data/lib/graphql/schema/member/instrumentation.rb +1 -6
  86. data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
  87. data/lib/graphql/schema/mutation.rb +1 -1
  88. data/lib/graphql/schema/object.rb +5 -6
  89. data/lib/graphql/schema/possible_types.rb +3 -3
  90. data/lib/graphql/schema/printer.rb +1 -3
  91. data/lib/graphql/schema/relay_classic_mutation.rb +2 -6
  92. data/lib/graphql/schema/resolver.rb +5 -35
  93. data/lib/graphql/schema/scalar.rb +1 -0
  94. data/lib/graphql/schema/subscription.rb +6 -6
  95. data/lib/graphql/schema/timeout_middleware.rb +2 -3
  96. data/lib/graphql/schema/type_expression.rb +27 -17
  97. data/lib/graphql/schema/union.rb +7 -26
  98. data/lib/graphql/schema/validation.rb +1 -17
  99. data/lib/graphql/schema/warden.rb +3 -77
  100. data/lib/graphql/schema/wrapper.rb +1 -1
  101. data/lib/graphql/static_validation/definition_dependencies.rb +12 -21
  102. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +9 -4
  103. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +10 -7
  104. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
  105. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
  106. data/lib/graphql/static_validation/rules/fields_will_merge.rb +4 -4
  107. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
  108. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -3
  109. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +5 -6
  110. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  111. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +1 -1
  112. data/lib/graphql/subscriptions.rb +7 -7
  113. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +2 -2
  114. data/lib/graphql/subscriptions/event.rb +5 -19
  115. data/lib/graphql/subscriptions/instrumentation.rb +9 -4
  116. data/lib/graphql/subscriptions/subscription_root.rb +2 -10
  117. data/lib/graphql/tracing/skylight_tracing.rb +0 -1
  118. data/lib/graphql/types/int.rb +1 -1
  119. data/lib/graphql/types/relay/base_connection.rb +3 -1
  120. data/lib/graphql/union_type.rb +23 -58
  121. data/lib/graphql/upgrader/member.rb +1 -1
  122. data/lib/graphql/version.rb +1 -1
  123. metadata +20 -13
  124. data/lib/generators/graphql/templates/base_mutation.erb +0 -8
  125. data/lib/graphql/schema/type_membership.rb +0 -34
@@ -58,7 +58,7 @@ module GraphQL
58
58
  # @param context [GraphQL::Query::Context]
59
59
  # @return [Boolean] If truthy, execution will continue
60
60
  def self.enabled?(flag_name, object, context)
61
- raise GraphQL::RequiredImplementationMissingError, "Implement `.enabled?(flag_name, object, context)` to return true or false for the feature flag (#{flag_name.inspect})"
61
+ raise NotImplementedError, "Implement `.enabled?(flag_name, object, context)` to return true or false for the feature flag (#{flag_name.inspect})"
62
62
  end
63
63
  end
64
64
  end
@@ -53,6 +53,7 @@ module GraphQL
53
53
  enum_type.name = graphql_name
54
54
  enum_type.description = description
55
55
  enum_type.introspection = introspection
56
+ enum_type.ast_node = ast_node
56
57
  values.each do |name, val|
57
58
  enum_type.add_value(val.to_graphql)
58
59
  end
@@ -28,6 +28,7 @@ module GraphQL
28
28
  class EnumValue < GraphQL::Schema::Member
29
29
  include GraphQL::Schema::Member::AcceptsDefinition
30
30
  include GraphQL::Schema::Member::HasPath
31
+ include GraphQL::Schema::Member::HasAstNode
31
32
 
32
33
  attr_reader :graphql_name
33
34
 
@@ -37,12 +38,13 @@ module GraphQL
37
38
  # @return [String] Explains why this value was deprecated (if present, this will be marked deprecated in introspection)
38
39
  attr_accessor :deprecation_reason
39
40
 
40
- def initialize(graphql_name, desc = nil, owner:, description: nil, value: nil, deprecation_reason: nil, &block)
41
+ def initialize(graphql_name, desc = nil, owner:, ast_node: nil, description: nil, value: nil, deprecation_reason: nil, &block)
41
42
  @graphql_name = graphql_name.to_s
42
43
  @description = desc || description
43
44
  @value = value.nil? ? @graphql_name : value
44
45
  @deprecation_reason = deprecation_reason
45
46
  @owner = owner
47
+ @ast_node = ast_node
46
48
 
47
49
  if block_given?
48
50
  instance_eval(&block)
@@ -71,6 +73,7 @@ module GraphQL
71
73
  enum_value.value = @value
72
74
  enum_value.deprecation_reason = @deprecation_reason
73
75
  enum_value.metadata[:type_class] = self
76
+ enum_value.ast_node = ast_node
74
77
  enum_value
75
78
  end
76
79
 
@@ -13,8 +13,8 @@ module GraphQL
13
13
  include GraphQL::Schema::Member::CachedGraphQLDefinition
14
14
  include GraphQL::Schema::Member::AcceptsDefinition
15
15
  include GraphQL::Schema::Member::HasArguments
16
+ include GraphQL::Schema::Member::HasAstNode
16
17
  include GraphQL::Schema::Member::HasPath
17
- extend GraphQL::Schema::FindInheritedValue
18
18
 
19
19
  # @return [String] the GraphQL name for this field, camelized unless `camelize: false` is provided
20
20
  attr_reader :name
@@ -37,7 +37,7 @@ module GraphQL
37
37
  # @return [Class] The type that this field belongs to
38
38
  attr_reader :owner
39
39
 
40
- # @return [Symobol] the original name of the field, passed in by the user
40
+ # @return [Symbol] the original name of the field, passed in by the user
41
41
  attr_reader :original_name
42
42
 
43
43
  # @return [Class, nil] The {Schema::Resolver} this field was derived from, if there is one
@@ -136,20 +136,9 @@ module GraphQL
136
136
  end
137
137
  end
138
138
 
139
- # This extension is applied to fields when {#connection?} is true.
140
- #
141
- # You can override it in your base field definition.
142
- # @return [Class] A {FieldExtension} subclass for implementing pagination behavior.
143
- # @example Configuring a custom extension
144
- # class Types::BaseField < GraphQL::Schema::Field
145
- # connection_extension(MyCustomExtension)
146
- # end
147
- def self.connection_extension(new_extension_class = nil)
148
- if new_extension_class
149
- @connection_extension = new_extension_class
150
- else
151
- @connection_extension ||= find_inherited_value(:connection_extension, ConnectionExtension)
152
- end
139
+ # @return [Boolean] Should we warn if this field's name conflicts with a built-in method?
140
+ def method_conflict_warning?
141
+ @method_conflict_warning
153
142
  end
154
143
 
155
144
  # @param name [Symbol] The underscore-cased version of this field name (will be camelized for the GraphQL API)
@@ -175,7 +164,9 @@ module GraphQL
175
164
  # @param subscription_scope [Symbol, String] A key in `context` which will be used to scope subscription payloads
176
165
  # @param extensions [Array<Class, Hash<Class => Object>>] Named extensions to apply to this field (see also {#extension})
177
166
  # @param trace [Boolean] If true, a {GraphQL::Tracing} tracer will measure this scalar field
178
- def initialize(type: nil, name: nil, owner: nil, null: nil, field: nil, function: nil, description: nil, deprecation_reason: nil, method: nil, hash_key: nil, resolver_method: nil, resolve: nil, connection: nil, max_page_size: nil, scope: nil, introspection: false, camelize: true, trace: nil, complexity: 1, extras: [], extensions: [], resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, arguments: {}, &definition_block)
167
+ # @param ast_node [Language::Nodes::FieldDefinition, nil] If this schema was parsed from definition, this AST node defined the field
168
+ # @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
169
+ def initialize(type: nil, name: nil, owner: nil, null: nil, field: nil, function: nil, description: nil, deprecation_reason: nil, method: nil, hash_key: nil, resolver_method: nil, resolve: nil, connection: nil, max_page_size: nil, scope: nil, introspection: false, camelize: true, trace: nil, complexity: 1, ast_node: nil, extras: [], extensions: [], resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, arguments: {}, &definition_block)
179
170
  if name.nil?
180
171
  raise ArgumentError, "missing first `name` argument or keyword `name:`"
181
172
  end
@@ -236,6 +227,8 @@ module GraphQL
236
227
  @trace = trace
237
228
  @relay_node_field = relay_node_field
238
229
  @relay_nodes_field = relay_nodes_field
230
+ @ast_node = ast_node
231
+ @method_conflict_warning = method_conflict_warning
239
232
 
240
233
  # Override the default from HasArguments
241
234
  @own_arguments = {}
@@ -263,7 +256,7 @@ module GraphQL
263
256
  # The problem with putting this after the definition_block
264
257
  # is that it would override arguments
265
258
  if connection?
266
- self.extension(self.class.connection_extension)
259
+ self.extension(ConnectionExtension)
267
260
  end
268
261
 
269
262
  if definition_block
@@ -416,6 +409,7 @@ module GraphQL
416
409
  field_defn.introspection = @introspection
417
410
  field_defn.complexity = @complexity
418
411
  field_defn.subscription_scope = @subscription_scope
412
+ field_defn.ast_node = ast_node
419
413
 
420
414
  arguments.each do |name, defn|
421
415
  arg_graphql = defn.to_graphql
@@ -439,8 +433,11 @@ module GraphQL
439
433
 
440
434
  def type
441
435
  @type ||= Member::BuildType.parse_type(@return_type_expr, null: @return_type_null)
442
- rescue
443
- raise ArgumentError, "Failed to build return type for #{@owner.graphql_name}.#{name} from #{@return_type_expr.inspect}: #{$!.message}", $!.backtrace
436
+ rescue GraphQL::Schema::InvalidDocumentError => err
437
+ # Let this propagate up
438
+ raise err
439
+ rescue StandardError => err
440
+ raise ArgumentError, "Failed to build return type for #{@owner.graphql_name}.#{name} from #{@return_type_expr.inspect}: (#{err.class}) #{err.message}", err.backtrace
444
441
  end
445
442
 
446
443
  def visible?(context)
@@ -459,14 +456,14 @@ module GraphQL
459
456
  end
460
457
  end
461
458
 
462
- def authorized?(object, context)
459
+ def authorized?(object, args, context)
463
460
  if @resolver_class
464
461
  # The resolver will check itself during `resolve()`
465
462
  @resolver_class.authorized?(object, context)
466
463
  else
467
464
  # Faster than `.any?`
468
465
  arguments.each_value do |arg|
469
- if !arg.authorized?(object, context)
466
+ if args.key?(arg.keyword) && !arg.authorized?(object, args[arg.keyword], context)
470
467
  return false
471
468
  end
472
469
  end
@@ -485,21 +482,22 @@ module GraphQL
485
482
  # Some legacy fields can have `nil` here, not exactly sure why.
486
483
  # @see https://github.com/rmosolgo/graphql-ruby/issues/1990 before removing
487
484
  inner_obj = after_obj && after_obj.object
488
- if authorized?(inner_obj, query_ctx)
489
- ruby_args = to_ruby_args(after_obj, args, ctx)
490
- # Then if it passed, resolve the field
491
- if @resolve_proc
492
- # Might be nil, still want to call the func in that case
493
- with_extensions(inner_obj, ruby_args, query_ctx) do |extended_obj, extended_args|
494
- # Pass the GraphQL args here for compatibility:
495
- @resolve_proc.call(extended_obj, args, ctx)
485
+ ctx.schema.after_lazy(to_ruby_args(after_obj, args, ctx)) do |ruby_args|
486
+ if authorized?(inner_obj, ruby_args, query_ctx)
487
+ # Then if it passed, resolve the field
488
+ if @resolve_proc
489
+ # Might be nil, still want to call the func in that case
490
+ with_extensions(inner_obj, ruby_args, query_ctx) do |extended_obj, extended_args|
491
+ # Pass the GraphQL args here for compatibility:
492
+ @resolve_proc.call(extended_obj, args, ctx)
493
+ end
494
+ else
495
+ public_send_field(after_obj, ruby_args, ctx)
496
496
  end
497
497
  else
498
- public_send_field(after_obj, ruby_args, ctx)
498
+ err = GraphQL::UnauthorizedFieldError.new(object: inner_obj, type: obj.class, context: ctx, field: self)
499
+ query_ctx.schema.unauthorized_field(err)
499
500
  end
500
- else
501
- err = GraphQL::UnauthorizedFieldError.new(object: inner_obj, type: obj.class, context: ctx, field: self)
502
- query_ctx.schema.unauthorized_field(err)
503
501
  end
504
502
  end
505
503
  end
@@ -516,7 +514,7 @@ module GraphQL
516
514
  begin
517
515
  # Unwrap the GraphQL object to get the application object.
518
516
  application_object = object.object
519
- if self.authorized?(application_object, ctx)
517
+ if self.authorized?(application_object, args, ctx)
520
518
  # Apply field extensions
521
519
  with_extensions(object, args, ctx) do |extended_obj, extended_args|
522
520
  field_receiver = if @resolver_class
@@ -525,7 +523,7 @@ module GraphQL
525
523
  else
526
524
  extended_obj
527
525
  end
528
- @resolver_class.new(object: resolver_obj, context: ctx, field: self)
526
+ @resolver_class.new(object: resolver_obj, context: ctx)
529
527
  else
530
528
  extended_obj
531
529
  end
@@ -594,12 +592,12 @@ module GraphQL
594
592
 
595
593
  # @param ctx [GraphQL::Query::Context::FieldResolutionContext]
596
594
  def fetch_extra(extra_name, ctx)
597
- if extra_name != :path && respond_to?(extra_name)
595
+ if extra_name != :path && extra_name != :ast_node && respond_to?(extra_name)
598
596
  self.public_send(extra_name)
599
597
  elsif ctx.respond_to?(extra_name)
600
598
  ctx.public_send(extra_name)
601
599
  else
602
- raise GraphQL::RequiredImplementationMissingError, "Unknown field extra for #{self.path}: #{extra_name.inspect}"
600
+ raise NotImplementedError, "Unknown field extra for #{self.path}: #{extra_name.inspect}"
603
601
  end
604
602
  end
605
603
 
@@ -642,7 +640,7 @@ module GraphQL
642
640
  if extended_obj.is_a?(GraphQL::Schema::Object)
643
641
  extended_obj = extended_obj.object
644
642
  end
645
- extended_obj = @resolver_class.new(object: extended_obj, context: query_ctx, field: self)
643
+ extended_obj = @resolver_class.new(object: extended_obj, context: query_ctx)
646
644
  end
647
645
 
648
646
  if extended_obj.respond_to?(@resolver_method)
@@ -28,6 +28,17 @@ module GraphQL
28
28
  nil
29
29
  elsif value.nil?
30
30
  nil
31
+ elsif value.is_a?(GraphQL::Pagination::Connection)
32
+ # update the connection with some things that may not have been provided
33
+ value.context ||= context
34
+ value.first ||= arguments[:first]
35
+ value.after ||= arguments[:after]
36
+ value.last ||= arguments[:last]
37
+ value.before ||= arguments[:before]
38
+ value.max_page_size ||= field.max_page_size
39
+ value
40
+ elsif context.schema.new_connections?
41
+ context.schema.connections.wrap(field, value, arguments, context)
31
42
  else
32
43
  if object.is_a?(GraphQL::Schema::Object)
33
44
  object = object.object
@@ -43,7 +54,6 @@ module GraphQL
43
54
  )
44
55
  end
45
56
  end
46
-
47
57
  end
48
58
  end
49
59
  end
@@ -26,7 +26,7 @@ module GraphQL
26
26
  if @ruby_style_hash.key?(ruby_kwargs_key) && loads && !arg_defn.from_resolver?
27
27
  value = @ruby_style_hash[ruby_kwargs_key]
28
28
  @ruby_style_hash[ruby_kwargs_key] = if arg_defn.type.list?
29
- GraphQL::Execution::Lazy.all(value.map { |val| load_application_object(arg_defn, loads, val) })
29
+ value.map { |val| load_application_object(arg_defn, loads, val) }
30
30
  else
31
31
  load_application_object(arg_defn, loads, value)
32
32
  end
@@ -57,10 +57,6 @@ module GraphQL
57
57
  to_h
58
58
  end
59
59
 
60
- def prepare
61
- self
62
- end
63
-
64
60
  def unwrap_value(value)
65
61
  case value
66
62
  when Array
@@ -117,6 +113,7 @@ module GraphQL
117
113
  type_defn.description = description
118
114
  type_defn.metadata[:type_class] = self
119
115
  type_defn.mutation = mutation
116
+ type_defn.ast_node = ast_node
120
117
  arguments.each do |name, arg|
121
118
  type_defn.arguments[arg.graphql_definition.name] = arg.graphql_definition
122
119
  end
@@ -12,6 +12,7 @@ module GraphQL
12
12
  include GraphQL::Schema::Member::HasPath
13
13
  include GraphQL::Schema::Member::RelayShortcuts
14
14
  include GraphQL::Schema::Member::Scoped
15
+ include GraphQL::Schema::Member::HasAstNode
15
16
 
16
17
  # Methods defined in this block will be:
17
18
  # - Added as class methods to this interface
@@ -89,6 +90,7 @@ module GraphQL
89
90
  type_defn.name = graphql_name
90
91
  type_defn.description = description
91
92
  type_defn.orphan_types = orphan_types
93
+ type_defn.ast_node = ast_node
92
94
  fields.each do |field_name, field_inst|
93
95
  field_defn = field_inst.graphql_definition
94
96
  type_defn.fields[field_defn.name] = field_defn
@@ -22,10 +22,7 @@ module GraphQL
22
22
  if schema.disable_introspection_entry_points
23
23
  {}
24
24
  else
25
- entry_point_fields = get_fields_from_class(class_sym: :EntryPoints)
26
- entry_point_fields.delete('__schema') if schema.disable_schema_introspection_entry_point
27
- entry_point_fields.delete('__type') if schema.disable_type_introspection_entry_point
28
- entry_point_fields
25
+ get_fields_from_class(class_sym: :EntryPoints)
29
26
  end
30
27
  @dynamic_fields = get_fields_from_class(class_sym: :DynamicFields)
31
28
  end
@@ -34,7 +34,7 @@ module GraphQL
34
34
  end
35
35
 
36
36
  NullResolveType = ->(type, obj, ctx) {
37
- raise(GraphQL::RequiredImplementationMissingError, "This schema was loaded from string, so it can't resolve types for objects")
37
+ raise(NotImplementedError, "This schema was loaded from string, so it can't resolve types for objects")
38
38
  }
39
39
 
40
40
  NullScalarCoerce = ->(val, _ctx) { val }
@@ -51,7 +51,7 @@ module GraphQL
51
51
  when "NON_NULL"
52
52
  NonNullType.new(of_type: resolve_type(types, type.fetch("ofType")))
53
53
  else
54
- fail GraphQL::RequiredImplementationMissingError, "#{kind} not implemented"
54
+ fail NotImplementedError, "#{kind} not implemented"
55
55
  end
56
56
  end
57
57
 
@@ -118,20 +118,14 @@ module GraphQL
118
118
  }]
119
119
  )
120
120
  when "FIELD"
121
- defns = {
121
+ GraphQL::Field.define(
122
122
  name: type["name"],
123
123
  type: type_resolver.call(type["type"]),
124
124
  description: type["description"],
125
- }
126
-
127
- # Avoid passing an empty hash, which warns on Ruby 2.7
128
- if type["args"].any?
129
- defns[:arguments] = Hash[type["args"].map { |arg|
125
+ arguments: Hash[type["args"].map { |arg|
130
126
  [arg["name"], define_type(arg.merge("kind" => "ARGUMENT"), type_resolver)]
131
127
  }]
132
- end
133
-
134
- GraphQL::Field.define(**defns)
128
+ )
135
129
  when "ARGUMENT"
136
130
  kwargs = {}
137
131
  if type["defaultValue"]
@@ -177,7 +171,7 @@ module GraphQL
177
171
  }
178
172
  )
179
173
  else
180
- fail GraphQL::RequiredImplementationMissingError, "#{type["kind"]} not implemented"
174
+ fail NotImplementedError, "#{type["kind"]} not implemented"
181
175
  end
182
176
  end
183
177
  end
@@ -3,6 +3,7 @@ require 'graphql/schema/member/accepts_definition'
3
3
  require 'graphql/schema/member/base_dsl_methods'
4
4
  require 'graphql/schema/member/cached_graphql_definition'
5
5
  require 'graphql/schema/member/graphql_type_names'
6
+ require 'graphql/schema/member/has_ast_node'
6
7
  require 'graphql/schema/member/has_path'
7
8
  require 'graphql/schema/member/relay_shortcuts'
8
9
  require 'graphql/schema/member/scoped'
@@ -24,6 +25,7 @@ module GraphQL
24
25
  extend Scoped
25
26
  extend RelayShortcuts
26
27
  extend HasPath
28
+ extend HasAstNode
27
29
  end
28
30
  end
29
31
  end
@@ -74,7 +74,7 @@ module GraphQL
74
74
 
75
75
  # @return [GraphQL::BaseType] Convert this type to a legacy-style object.
76
76
  def to_graphql
77
- raise GraphQL::RequiredImplementationMissingError
77
+ raise NotImplementedError
78
78
  end
79
79
 
80
80
  alias :unwrap :itself
@@ -88,7 +88,7 @@ module GraphQL
88
88
  # without any namespaces and with any `-Type` suffix removed
89
89
  def default_graphql_name
90
90
  @default_graphql_name ||= begin
91
- raise GraphQL::RequiredImplementationMissingError, 'Anonymous class should declare a `graphql_name`' if name.nil?
91
+ raise NotImplementedError, 'Anonymous class should declare a `graphql_name`' if name.nil?
92
92
 
93
93
  name.split("::").last.sub(/Type\Z/, "")
94
94
  end
@@ -64,6 +64,8 @@ module GraphQL
64
64
  else
65
65
  raise ArgumentError, LIST_TYPE_ERROR
66
66
  end
67
+ when GraphQL::Schema::NonNull, GraphQL::Schema::List
68
+ type_expr
67
69
  when Module
68
70
  # This is a way to check that it's the right kind of module:
69
71
  if type_expr.respond_to?(:graphql_definition)
@@ -72,6 +74,8 @@ module GraphQL
72
74
  # Eg `String` => GraphQL::STRING_TYPE
73
75
  parse_type(type_expr.name, null: true)
74
76
  end
77
+ when Proc
78
+ parse_type(type_expr.call, null: true)
75
79
  when false
76
80
  raise ArgumentError, "Received `false` instead of a type, maybe a `!` should be replaced with `null: true` (for fields) or `required: true` (for arguments)"
77
81
  end
@@ -15,6 +15,11 @@ module GraphQL
15
15
  @graphql_definition ||= to_graphql
16
16
  end
17
17
 
18
+ # This is for a common interface with .define-based types
19
+ def type_class
20
+ self
21
+ end
22
+
18
23
  # Wipe out the cached graphql_definition so that `.to_graphql` will be called again.
19
24
  def initialize_copy(original)
20
25
  super
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Schema
4
+ class Member
5
+ module HasAstNode
6
+ # If this schema was parsed from a `.graphql` file (or other SDL),
7
+ # this is the AST node that defined this part of the schema.
8
+ def ast_node(new_ast_node = nil)
9
+ if new_ast_node
10
+ @ast_node = new_ast_node
11
+ end
12
+ @ast_node
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end