graphql 1.13.17 → 2.0.20

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.

Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install_generator.rb +1 -1
  3. data/lib/generators/graphql/relay.rb +3 -17
  4. data/lib/generators/graphql/templates/schema.erb +3 -0
  5. data/lib/graphql/analysis/ast/field_usage.rb +3 -1
  6. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
  7. data/lib/graphql/analysis/ast/query_complexity.rb +1 -1
  8. data/lib/graphql/analysis/ast/query_depth.rb +0 -1
  9. data/lib/graphql/analysis/ast/visitor.rb +43 -36
  10. data/lib/graphql/analysis/ast.rb +2 -12
  11. data/lib/graphql/analysis.rb +0 -7
  12. data/lib/graphql/backtrace/table.rb +2 -20
  13. data/lib/graphql/backtrace/tracer.rb +2 -3
  14. data/lib/graphql/backtrace.rb +2 -8
  15. data/lib/graphql/dataloader/null_dataloader.rb +3 -1
  16. data/lib/graphql/dataloader/source.rb +9 -0
  17. data/lib/graphql/dataloader.rb +4 -1
  18. data/lib/graphql/dig.rb +1 -1
  19. data/lib/graphql/execution/errors.rb +12 -82
  20. data/lib/graphql/execution/interpreter/resolve.rb +26 -0
  21. data/lib/graphql/execution/interpreter/runtime.rb +159 -120
  22. data/lib/graphql/execution/interpreter.rb +187 -78
  23. data/lib/graphql/execution/lazy.rb +7 -21
  24. data/lib/graphql/execution/lookahead.rb +44 -40
  25. data/lib/graphql/execution/multiplex.rb +3 -174
  26. data/lib/graphql/execution.rb +11 -4
  27. data/lib/graphql/introspection/directive_type.rb +2 -2
  28. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  29. data/lib/graphql/introspection/entry_points.rb +2 -15
  30. data/lib/graphql/introspection/field_type.rb +1 -1
  31. data/lib/graphql/introspection/schema_type.rb +2 -2
  32. data/lib/graphql/introspection/type_type.rb +13 -6
  33. data/lib/graphql/introspection.rb +4 -3
  34. data/lib/graphql/language/document_from_schema_definition.rb +18 -35
  35. data/lib/graphql/language/lexer.rb +216 -1488
  36. data/lib/graphql/language/nodes.rb +65 -39
  37. data/lib/graphql/language/parser.rb +376 -364
  38. data/lib/graphql/language/parser.y +49 -44
  39. data/lib/graphql/language/printer.rb +37 -21
  40. data/lib/graphql/language/visitor.rb +191 -83
  41. data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
  42. data/lib/graphql/pagination/array_connection.rb +4 -2
  43. data/lib/graphql/pagination/connection.rb +31 -4
  44. data/lib/graphql/pagination/connections.rb +3 -28
  45. data/lib/graphql/pagination/relation_connection.rb +2 -0
  46. data/lib/graphql/query/context.rb +155 -196
  47. data/lib/graphql/query/input_validation_result.rb +1 -1
  48. data/lib/graphql/query/null_context.rb +0 -3
  49. data/lib/graphql/query/validation_pipeline.rb +10 -34
  50. data/lib/graphql/query/variables.rb +7 -20
  51. data/lib/graphql/query.rb +32 -42
  52. data/lib/graphql/railtie.rb +0 -104
  53. data/lib/graphql/rake_task/validate.rb +1 -1
  54. data/lib/graphql/rake_task.rb +29 -1
  55. data/lib/graphql/relay/range_add.rb +9 -20
  56. data/lib/graphql/relay.rb +0 -15
  57. data/lib/graphql/schema/addition.rb +7 -9
  58. data/lib/graphql/schema/argument.rb +36 -43
  59. data/lib/graphql/schema/build_from_definition.rb +32 -18
  60. data/lib/graphql/schema/directive/one_of.rb +12 -0
  61. data/lib/graphql/schema/directive/transform.rb +1 -1
  62. data/lib/graphql/schema/directive.rb +12 -23
  63. data/lib/graphql/schema/enum.rb +28 -39
  64. data/lib/graphql/schema/enum_value.rb +5 -25
  65. data/lib/graphql/schema/field/connection_extension.rb +4 -0
  66. data/lib/graphql/schema/field.rb +237 -339
  67. data/lib/graphql/schema/input_object.rb +56 -67
  68. data/lib/graphql/schema/interface.rb +0 -35
  69. data/lib/graphql/schema/introspection_system.rb +3 -8
  70. data/lib/graphql/schema/late_bound_type.rb +8 -2
  71. data/lib/graphql/schema/list.rb +0 -6
  72. data/lib/graphql/schema/loader.rb +1 -2
  73. data/lib/graphql/schema/member/base_dsl_methods.rb +17 -19
  74. data/lib/graphql/schema/member/build_type.rb +5 -7
  75. data/lib/graphql/schema/member/has_arguments.rb +146 -55
  76. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  77. data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
  78. data/lib/graphql/schema/member/has_directives.rb +81 -59
  79. data/lib/graphql/schema/member/has_fields.rb +17 -4
  80. data/lib/graphql/schema/member/has_interfaces.rb +49 -10
  81. data/lib/graphql/schema/member/has_validators.rb +31 -5
  82. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  83. data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
  84. data/lib/graphql/schema/member/validates_input.rb +1 -1
  85. data/lib/graphql/schema/member.rb +0 -6
  86. data/lib/graphql/schema/mutation.rb +0 -9
  87. data/lib/graphql/schema/non_null.rb +1 -7
  88. data/lib/graphql/schema/object.rb +15 -52
  89. data/lib/graphql/schema/relay_classic_mutation.rb +53 -42
  90. data/lib/graphql/schema/resolver/has_payload_type.rb +20 -10
  91. data/lib/graphql/schema/resolver.rb +41 -42
  92. data/lib/graphql/schema/scalar.rb +7 -22
  93. data/lib/graphql/schema/subscription.rb +0 -7
  94. data/lib/graphql/schema/timeout.rb +24 -28
  95. data/lib/graphql/schema/type_membership.rb +3 -0
  96. data/lib/graphql/schema/union.rb +10 -17
  97. data/lib/graphql/schema/warden.rb +34 -8
  98. data/lib/graphql/schema/wrapper.rb +0 -5
  99. data/lib/graphql/schema.rb +241 -973
  100. data/lib/graphql/static_validation/all_rules.rb +1 -0
  101. data/lib/graphql/static_validation/base_visitor.rb +4 -21
  102. data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
  103. data/lib/graphql/static_validation/error.rb +2 -2
  104. data/lib/graphql/static_validation/literal_validator.rb +19 -1
  105. data/lib/graphql/static_validation/rules/directives_are_defined.rb +11 -5
  106. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
  107. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  108. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  109. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +12 -6
  110. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
  111. data/lib/graphql/static_validation/validator.rb +3 -25
  112. data/lib/graphql/static_validation.rb +0 -2
  113. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -1
  114. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
  115. data/lib/graphql/subscriptions/event.rb +3 -8
  116. data/lib/graphql/subscriptions/instrumentation.rb +0 -51
  117. data/lib/graphql/subscriptions.rb +32 -20
  118. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  119. data/lib/graphql/tracing/appoptics_trace.rb +231 -0
  120. data/lib/graphql/tracing/appsignal_trace.rb +71 -0
  121. data/lib/graphql/tracing/data_dog_trace.rb +148 -0
  122. data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
  123. data/lib/graphql/tracing/new_relic_trace.rb +75 -0
  124. data/lib/graphql/tracing/notifications_trace.rb +41 -0
  125. data/lib/graphql/tracing/platform_trace.rb +107 -0
  126. data/lib/graphql/tracing/platform_tracing.rb +26 -40
  127. data/lib/graphql/tracing/prometheus_trace.rb +89 -0
  128. data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
  129. data/lib/graphql/tracing/scout_trace.rb +72 -0
  130. data/lib/graphql/tracing/statsd_trace.rb +56 -0
  131. data/lib/graphql/tracing.rb +136 -40
  132. data/lib/graphql/type_kinds.rb +6 -3
  133. data/lib/graphql/types/iso_8601_date.rb +4 -1
  134. data/lib/graphql/types/iso_8601_date_time.rb +4 -0
  135. data/lib/graphql/types/relay/base_connection.rb +16 -6
  136. data/lib/graphql/types/relay/connection_behaviors.rb +29 -27
  137. data/lib/graphql/types/relay/edge_behaviors.rb +16 -5
  138. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  139. data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
  140. data/lib/graphql/types/relay.rb +0 -3
  141. data/lib/graphql/types/string.rb +1 -1
  142. data/lib/graphql/version.rb +1 -1
  143. data/lib/graphql.rb +13 -74
  144. metadata +30 -133
  145. data/lib/graphql/analysis/analyze_query.rb +0 -98
  146. data/lib/graphql/analysis/field_usage.rb +0 -45
  147. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  148. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  149. data/lib/graphql/analysis/query_complexity.rb +0 -88
  150. data/lib/graphql/analysis/query_depth.rb +0 -43
  151. data/lib/graphql/analysis/reducer_state.rb +0 -48
  152. data/lib/graphql/argument.rb +0 -131
  153. data/lib/graphql/authorization.rb +0 -82
  154. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  155. data/lib/graphql/backwards_compatibility.rb +0 -61
  156. data/lib/graphql/base_type.rb +0 -232
  157. data/lib/graphql/boolean_type.rb +0 -2
  158. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  159. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  160. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  161. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  162. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  163. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  164. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  165. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  166. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  167. data/lib/graphql/compatibility.rb +0 -5
  168. data/lib/graphql/define/assign_argument.rb +0 -12
  169. data/lib/graphql/define/assign_connection.rb +0 -13
  170. data/lib/graphql/define/assign_enum_value.rb +0 -18
  171. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  172. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  173. data/lib/graphql/define/assign_object_field.rb +0 -42
  174. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  175. data/lib/graphql/define/instance_definable.rb +0 -255
  176. data/lib/graphql/define/no_definition_error.rb +0 -7
  177. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  178. data/lib/graphql/define/type_definer.rb +0 -31
  179. data/lib/graphql/define.rb +0 -31
  180. data/lib/graphql/deprecated_dsl.rb +0 -55
  181. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  182. data/lib/graphql/directive/include_directive.rb +0 -2
  183. data/lib/graphql/directive/skip_directive.rb +0 -2
  184. data/lib/graphql/directive.rb +0 -107
  185. data/lib/graphql/enum_type.rb +0 -133
  186. data/lib/graphql/execution/execute.rb +0 -333
  187. data/lib/graphql/execution/flatten.rb +0 -40
  188. data/lib/graphql/execution/instrumentation.rb +0 -92
  189. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  190. data/lib/graphql/execution/typecast.rb +0 -50
  191. data/lib/graphql/field/resolve.rb +0 -59
  192. data/lib/graphql/field.rb +0 -226
  193. data/lib/graphql/float_type.rb +0 -2
  194. data/lib/graphql/function.rb +0 -128
  195. data/lib/graphql/id_type.rb +0 -2
  196. data/lib/graphql/input_object_type.rb +0 -138
  197. data/lib/graphql/int_type.rb +0 -2
  198. data/lib/graphql/interface_type.rb +0 -72
  199. data/lib/graphql/internal_representation/document.rb +0 -27
  200. data/lib/graphql/internal_representation/node.rb +0 -206
  201. data/lib/graphql/internal_representation/print.rb +0 -51
  202. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  203. data/lib/graphql/internal_representation/scope.rb +0 -88
  204. data/lib/graphql/internal_representation/visit.rb +0 -36
  205. data/lib/graphql/internal_representation.rb +0 -7
  206. data/lib/graphql/language/lexer.rl +0 -260
  207. data/lib/graphql/list_type.rb +0 -80
  208. data/lib/graphql/non_null_type.rb +0 -71
  209. data/lib/graphql/object_type.rb +0 -130
  210. data/lib/graphql/query/arguments.rb +0 -189
  211. data/lib/graphql/query/arguments_cache.rb +0 -24
  212. data/lib/graphql/query/executor.rb +0 -52
  213. data/lib/graphql/query/literal_input.rb +0 -136
  214. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  215. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  216. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  217. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  218. data/lib/graphql/query/serial_execution.rb +0 -40
  219. data/lib/graphql/relay/array_connection.rb +0 -83
  220. data/lib/graphql/relay/base_connection.rb +0 -189
  221. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  222. data/lib/graphql/relay/connection_resolve.rb +0 -43
  223. data/lib/graphql/relay/connection_type.rb +0 -54
  224. data/lib/graphql/relay/edge.rb +0 -27
  225. data/lib/graphql/relay/edge_type.rb +0 -19
  226. data/lib/graphql/relay/edges_instrumentation.rb +0 -39
  227. data/lib/graphql/relay/global_id_resolve.rb +0 -17
  228. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  229. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  230. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  231. data/lib/graphql/relay/mutation/result.rb +0 -38
  232. data/lib/graphql/relay/mutation.rb +0 -106
  233. data/lib/graphql/relay/node.rb +0 -39
  234. data/lib/graphql/relay/page_info.rb +0 -7
  235. data/lib/graphql/relay/relation_connection.rb +0 -188
  236. data/lib/graphql/relay/type_extensions.rb +0 -32
  237. data/lib/graphql/scalar_type.rb +0 -91
  238. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  239. data/lib/graphql/schema/default_parse_error.rb +0 -10
  240. data/lib/graphql/schema/default_type_error.rb +0 -17
  241. data/lib/graphql/schema/member/accepts_definition.rb +0 -164
  242. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
  243. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  244. data/lib/graphql/schema/middleware_chain.rb +0 -82
  245. data/lib/graphql/schema/possible_types.rb +0 -44
  246. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  247. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  248. data/lib/graphql/schema/traversal.rb +0 -228
  249. data/lib/graphql/schema/validation.rb +0 -313
  250. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  251. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  252. data/lib/graphql/string_type.rb +0 -2
  253. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  254. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  255. data/lib/graphql/types/relay/default_relay.rb +0 -31
  256. data/lib/graphql/types/relay/node_field.rb +0 -24
  257. data/lib/graphql/types/relay/nodes_field.rb +0 -43
  258. data/lib/graphql/union_type.rb +0 -115
  259. data/lib/graphql/upgrader/member.rb +0 -937
  260. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- # @api deprecated
4
- class InterfaceType < GraphQL::BaseType
5
- extend Define::InstanceDefinable::DeprecatedDefine
6
-
7
- deprecated_accepts_definitions :fields, :orphan_types, :resolve_type, field: GraphQL::Define::AssignObjectField
8
-
9
- attr_accessor :fields, :orphan_types, :resolve_type_proc
10
- attr_writer :type_membership_class
11
- ensure_defined :fields, :orphan_types, :resolve_type_proc, :resolve_type
12
-
13
- def initialize
14
- super
15
- @fields = {}
16
- @orphan_types = []
17
- @resolve_type_proc = nil
18
- end
19
-
20
- def initialize_copy(other)
21
- super
22
- @fields = other.fields.dup
23
- @orphan_types = other.orphan_types.dup
24
- end
25
-
26
- def kind
27
- GraphQL::TypeKinds::INTERFACE
28
- end
29
-
30
- def resolve_type(value, ctx)
31
- ctx.query.resolve_type(self, value)
32
- end
33
-
34
- def resolve_type=(resolve_type_callable)
35
- @resolve_type_proc = resolve_type_callable
36
- end
37
-
38
- # @return [GraphQL::Field] The defined field for `field_name`
39
- def get_field(field_name)
40
- fields[field_name]
41
- end
42
-
43
- # These fields don't have instrumenation applied
44
- # @see [Schema#get_fields] Get fields with instrumentation
45
- # @return [Array<GraphQL::Field>] All fields on this type
46
- def all_fields
47
- fields.values
48
- end
49
-
50
- # Get a possible type of this {InterfaceType} by type name
51
- # @param type_name [String]
52
- # @param ctx [GraphQL::Query::Context] The context for the current query
53
- # @return [GraphQL::ObjectType, nil] The type named `type_name` if it exists and implements this {InterfaceType}, (else `nil`)
54
- def get_possible_type(type_name, ctx)
55
- type = ctx.query.get_type(type_name)
56
- type if type && ctx.query.warden.possible_types(self).include?(type)
57
- end
58
-
59
- # Check if a type is a possible type of this {InterfaceType}
60
- # @param type [String, GraphQL::BaseType] Name of the type or a type definition
61
- # @param ctx [GraphQL::Query::Context] The context for the current query
62
- # @return [Boolean] True if the `type` exists and is a member of this {InterfaceType}, (else `nil`)
63
- def possible_type?(type, ctx)
64
- type_name = type.is_a?(String) ? type : type.graphql_name
65
- !get_possible_type(type_name, ctx).nil?
66
- end
67
-
68
- def type_membership_class
69
- @type_membership_class || GraphQL::Schema::TypeMembership
70
- end
71
- end
72
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module InternalRepresentation
4
- class Document
5
- # @return [Hash<String, Node>] Operation Nodes of this query
6
- attr_reader :operation_definitions
7
-
8
- # @return [Hash<String, Node>] Fragment definition Nodes of this query
9
- attr_reader :fragment_definitions
10
-
11
- def initialize
12
- @operation_definitions = {}
13
- @fragment_definitions = {}
14
- end
15
-
16
- def [](key)
17
- GraphQL::Deprecation.warn "#{self.class}#[] is deprecated; use `operation_definitions[]` instead"
18
- operation_definitions[key]
19
- end
20
-
21
- def each(&block)
22
- GraphQL::Deprecation.warn "#{self.class}#each is deprecated; use `operation_definitions.each` instead"
23
- operation_definitions.each(&block)
24
- end
25
- end
26
- end
27
- end
@@ -1,206 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module InternalRepresentation
4
- class Node
5
- # @api private
6
- DEFAULT_TYPED_CHILDREN = Proc.new { |h, k| h[k] = {} }
7
-
8
- # A specialized, reusable object for leaf nodes.
9
- NO_TYPED_CHILDREN = Hash.new({}.freeze)
10
- def NO_TYPED_CHILDREN.dup; self; end;
11
- NO_TYPED_CHILDREN.freeze
12
-
13
- # @return [String] the name this node has in the response
14
- attr_reader :name
15
-
16
- # @return [GraphQL::ObjectType]
17
- attr_reader :owner_type
18
-
19
- # Each key is a {GraphQL::ObjectType} which this selection _may_ be made on.
20
- # The values for that key are selections which apply to that type.
21
- #
22
- # This value is derived from {#scoped_children} after the rewrite is finished.
23
- # @return [Hash<GraphQL::ObjectType, Hash<String => Node>>]
24
- def typed_children
25
- @typed_children ||= begin
26
- if @scoped_children.any?
27
- new_tc = Hash.new(&DEFAULT_TYPED_CHILDREN)
28
- all_object_types = Set.new
29
- scoped_children.each_key { |t| all_object_types.merge(@query.possible_types(t)) }
30
- # Remove any scoped children which don't follow this return type
31
- # (This can happen with fragment merging where lexical scope is lost)
32
- all_object_types &= @query.possible_types(@return_type.unwrap)
33
- all_object_types.each do |t|
34
- new_tc[t] = get_typed_children(t)
35
- end
36
- new_tc
37
- else
38
- NO_TYPED_CHILDREN
39
- end
40
-
41
- end
42
- end
43
-
44
- # These children correspond closely to scopes in the AST.
45
- # Keys _may_ be abstract types. They're assumed to be read-only after rewrite is finished
46
- # because {#typed_children} is derived from them.
47
- #
48
- # Using {#scoped_children} during the rewrite step reduces the overhead of reifying
49
- # abstract types because they're only reified _after_ the rewrite.
50
- # @return [Hash<GraphQL::BaseType, Hash<String => Node>>]
51
- attr_reader :scoped_children
52
-
53
- # @return [Array<Language::Nodes::AbstractNode>] AST nodes which are represented by this node
54
- attr_reader :ast_nodes
55
-
56
- # @return [Array<GraphQL::Field>] Field definitions for this node (there should only be one!)
57
- attr_reader :definitions
58
-
59
- # @return [GraphQL::BaseType] The expected wrapped type this node must return.
60
- attr_reader :return_type
61
-
62
- # @return [InternalRepresentation::Node, nil]
63
- attr_reader :parent
64
-
65
- def initialize(
66
- name:, owner_type:, query:, return_type:, parent:,
67
- ast_nodes: [],
68
- definitions: []
69
- )
70
- @name = name
71
- @query = query
72
- @owner_type = owner_type
73
- @parent = parent
74
- @typed_children = nil
75
- @scoped_children = Hash.new { |h1, k1| h1[k1] = {} }
76
- @ast_nodes = ast_nodes
77
- @definitions = definitions
78
- @return_type = return_type
79
- end
80
-
81
- def initialize_copy(other_node)
82
- super
83
- # Bust some caches:
84
- @typed_children = nil
85
- @definition = nil
86
- @definition_name = nil
87
- @ast_node = nil
88
- # Shallow-copy some state:
89
- @scoped_children = other_node.scoped_children.dup
90
- @ast_nodes = other_node.ast_nodes.dup
91
- @definitions = other_node.definitions.dup
92
- end
93
-
94
- def ==(other)
95
- other.is_a?(self.class) &&
96
- other.name == name &&
97
- other.parent == parent &&
98
- other.return_type == return_type &&
99
- other.owner_type == owner_type &&
100
- other.scoped_children == scoped_children &&
101
- other.definitions == definitions &&
102
- other.ast_nodes == ast_nodes
103
- end
104
-
105
- def definition_name
106
- definition && definition.name
107
- end
108
-
109
- def arguments
110
- @query.arguments_for(self, definition)
111
- end
112
-
113
- def definition
114
- @definition ||= begin
115
- first_def = @definitions.first
116
- first_def && @query.get_field(@owner_type, first_def.name)
117
- end
118
- end
119
-
120
- def ast_node
121
- @ast_node ||= ast_nodes.first
122
- end
123
-
124
- def inspect
125
- all_children_names = scoped_children.values.map(&:keys).flatten.uniq.join(", ")
126
- all_locations = ast_nodes.map {|n| "#{n.line}:#{n.col}" }.join(", ")
127
- "#<Node #{@owner_type}.#{@name} -> #{@return_type} {#{all_children_names}} @ [#{all_locations}] #{object_id}>"
128
- end
129
-
130
- # Merge selections from `new_parent` into `self`.
131
- # Selections are merged in place, not copied.
132
- def deep_merge_node(new_parent, scope: nil, merge_self: true)
133
- if merge_self
134
- @ast_nodes |= new_parent.ast_nodes
135
- @definitions |= new_parent.definitions
136
- end
137
- new_sc = new_parent.scoped_children
138
- if new_sc.any?
139
- scope ||= Scope.new(@query, @return_type.unwrap)
140
- new_sc.each do |obj_type, new_fields|
141
- inner_scope = scope.enter(obj_type)
142
- inner_scope.each do |scoped_type|
143
- prev_fields = @scoped_children[scoped_type]
144
- new_fields.each do |name, new_node|
145
- prev_node = prev_fields[name]
146
- if prev_node
147
- prev_node.deep_merge_node(new_node)
148
- else
149
- prev_fields[name] = new_node
150
- end
151
- end
152
- end
153
- end
154
- end
155
- end
156
-
157
- # @return [GraphQL::Query]
158
- attr_reader :query
159
-
160
- def subscription_topic
161
- @subscription_topic ||= begin
162
- scope = if definition.subscription_scope
163
- @query.context[definition.subscription_scope]
164
- else
165
- nil
166
- end
167
- Subscriptions::Event.serialize(
168
- definition_name,
169
- @query.arguments_for(self, definition),
170
- definition,
171
- scope: scope
172
- )
173
- end
174
- end
175
-
176
- protected
177
-
178
- attr_writer :owner_type, :parent
179
-
180
- private
181
-
182
- # Get applicable children from {#scoped_children}
183
- # @param obj_type [GraphQL::ObjectType]
184
- # @return [Hash<String => Node>]
185
- def get_typed_children(obj_type)
186
- new_tc = {}
187
- @scoped_children.each do |scope_type, scope_nodes|
188
- if GraphQL::Execution::Typecast.subtype?(scope_type, obj_type)
189
- scope_nodes.each do |name, new_node|
190
- prev_node = new_tc[name]
191
- if prev_node
192
- prev_node.deep_merge_node(new_node)
193
- else
194
- copied_node = new_node.dup
195
- copied_node.owner_type = obj_type
196
- copied_node.parent = self
197
- new_tc[name] = copied_node
198
- end
199
- end
200
- end
201
- end
202
- new_tc
203
- end
204
- end
205
- end
206
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module InternalRepresentation
4
- module Print
5
- module_function
6
-
7
- def print(schema, query_string)
8
- query = GraphQL::Query.new(schema, query_string)
9
- print_node(query.irep_selection)
10
- end
11
-
12
- def print_node(node, indent: 0)
13
- padding = " " * indent
14
- typed_children_padding = " " * (indent + 2)
15
- query_str = "".dup
16
-
17
- if !node.definition
18
- op_node = node.ast_node
19
- name = op_node.name ? " " + op_node.name : ""
20
- op_type = op_node.operation_type
21
- query_str << "#{op_type}#{name}"
22
- else
23
- if node.name == node.definition_name
24
- query_str << "#{padding}#{node.name}"
25
- else
26
- query_str << "#{padding}#{node.name}: #{node.definition_name}"
27
- end
28
-
29
- args = node.ast_nodes.map { |n| n.arguments.map(&:to_query_string).join(",") }.uniq
30
- query_str << args.map { |a| "(#{a})"}.join("|")
31
- end
32
-
33
- if node.typed_children.any?
34
- query_str << " {\n"
35
- node.typed_children.each do |type, children|
36
- query_str << "#{typed_children_padding}... on #{type.name} {\n"
37
- children.each do |name, child|
38
- query_str << print_node(child, indent: indent + 4)
39
- end
40
- query_str << "#{typed_children_padding}}\n"
41
- end
42
- query_str << "#{padding}}\n"
43
- else
44
- query_str << "\n"
45
- end
46
-
47
- query_str
48
- end
49
- end
50
- end
51
- end
@@ -1,184 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module InternalRepresentation
4
- # While visiting an AST, build a normalized, flattened tree of {InternalRepresentation::Node}s.
5
- #
6
- # No unions or interfaces are present in this tree, only object types.
7
- #
8
- # Selections from the AST are attached to the object types they apply to.
9
- #
10
- # Inline fragments and fragment spreads are preserved in {InternalRepresentation::Node#ast_spreads},
11
- # where they can be used to check for the presence of directives. This might not be sufficient
12
- # for future directives, since the selections' grouping is lost.
13
- #
14
- # The rewritten query tree serves as the basis for the `FieldsWillMerge` validation.
15
- #
16
- module Rewrite
17
- include GraphQL::Language
18
-
19
- NO_DIRECTIVES = [].freeze
20
-
21
- # @return InternalRepresentation::Document
22
- attr_reader :rewrite_document
23
-
24
- def initialize(*)
25
- super
26
- @query = context.query
27
- @rewrite_document = InternalRepresentation::Document.new
28
- # Hash<Nodes::FragmentSpread => Set<InternalRepresentation::Node>>
29
- # A record of fragment spreads and the irep nodes that used them
30
- @rewrite_spread_parents = Hash.new { |h, k| h[k] = Set.new }
31
- # Hash<Nodes::FragmentSpread => Scope>
32
- @rewrite_spread_scopes = {}
33
- # Array<Set<InternalRepresentation::Node>>
34
- # The current point of the irep_tree during visitation
35
- @rewrite_nodes_stack = []
36
- # Array<Scope>
37
- @rewrite_scopes_stack = []
38
- @rewrite_skip_nodes = Set.new
39
-
40
- # Resolve fragment spreads.
41
- # Fragment definitions got their own irep trees during visitation.
42
- # Those nodes are spliced in verbatim (not copied), but this is OK
43
- # because fragments are resolved from the "bottom up", each fragment
44
- # can be shared between its usages.
45
- context.on_dependency_resolve do |defn_ast_node, spread_ast_nodes, frag_ast_node|
46
- frag_name = frag_ast_node.name
47
- fragment_node = @rewrite_document.fragment_definitions[frag_name]
48
-
49
- if fragment_node
50
- spread_ast_nodes.each do |spread_ast_node|
51
- parent_nodes = @rewrite_spread_parents[spread_ast_node]
52
- parent_scope = @rewrite_spread_scopes[spread_ast_node]
53
- parent_nodes.each do |parent_node|
54
- parent_node.deep_merge_node(fragment_node, scope: parent_scope, merge_self: false)
55
- end
56
- end
57
- end
58
- end
59
- end
60
-
61
- # @return [Hash<String, Node>] Roots of this query
62
- def operations
63
- GraphQL::Deprecation.warn "#{self.class}#operations is deprecated; use `document.operation_definitions` instead"
64
- @document.operation_definitions
65
- end
66
-
67
- def on_operation_definition(ast_node, parent)
68
- push_root_node(ast_node, @rewrite_document.operation_definitions) { super }
69
- end
70
-
71
- def on_fragment_definition(ast_node, parent)
72
- push_root_node(ast_node, @rewrite_document.fragment_definitions) { super }
73
- end
74
-
75
- def push_root_node(ast_node, definitions)
76
- # Either QueryType or the fragment type condition
77
- owner_type = context.type_definition
78
- defn_name = ast_node.name
79
-
80
- node = Node.new(
81
- parent: nil,
82
- name: defn_name,
83
- owner_type: owner_type,
84
- query: @query,
85
- ast_nodes: [ast_node],
86
- return_type: owner_type,
87
- )
88
-
89
- definitions[defn_name] = node
90
- @rewrite_scopes_stack.push(Scope.new(@query, owner_type))
91
- @rewrite_nodes_stack.push([node])
92
- yield
93
- @rewrite_nodes_stack.pop
94
- @rewrite_scopes_stack.pop
95
- end
96
-
97
- def on_inline_fragment(node, parent)
98
- # Inline fragments provide two things to the rewritten tree:
99
- # - They _may_ narrow the scope by their type condition
100
- # - They _may_ apply their directives to their children
101
- if skip?(node)
102
- @rewrite_skip_nodes.add(node)
103
- end
104
-
105
- if @rewrite_skip_nodes.empty?
106
- @rewrite_scopes_stack.push(@rewrite_scopes_stack.last.enter(context.type_definition))
107
- end
108
-
109
- super
110
-
111
- if @rewrite_skip_nodes.empty?
112
- @rewrite_scopes_stack.pop
113
- end
114
-
115
- if @rewrite_skip_nodes.include?(node)
116
- @rewrite_skip_nodes.delete(node)
117
- end
118
- end
119
-
120
- def on_field(ast_node, ast_parent)
121
- if skip?(ast_node)
122
- @rewrite_skip_nodes.add(ast_node)
123
- end
124
-
125
- if @rewrite_skip_nodes.empty?
126
- node_name = ast_node.alias || ast_node.name
127
- parent_nodes = @rewrite_nodes_stack.last
128
- next_nodes = []
129
-
130
- field_defn = context.field_definition
131
- if field_defn.nil?
132
- # It's a non-existent field
133
- new_scope = nil
134
- else
135
- field_return_type = field_defn.type
136
- @rewrite_scopes_stack.last.each do |scope_type|
137
- parent_nodes.each do |parent_node|
138
- node = parent_node.scoped_children[scope_type][node_name] ||= Node.new(
139
- parent: parent_node,
140
- name: node_name,
141
- owner_type: scope_type,
142
- query: @query,
143
- return_type: field_return_type,
144
- )
145
- node.ast_nodes << ast_node
146
- node.definitions << field_defn
147
- next_nodes << node
148
- end
149
- end
150
- new_scope = Scope.new(@query, field_return_type.unwrap)
151
- end
152
-
153
- @rewrite_nodes_stack.push(next_nodes)
154
- @rewrite_scopes_stack.push(new_scope)
155
- end
156
-
157
- super
158
-
159
- if @rewrite_skip_nodes.empty?
160
- @rewrite_nodes_stack.pop
161
- @rewrite_scopes_stack.pop
162
- end
163
-
164
- if @rewrite_skip_nodes.include?(ast_node)
165
- @rewrite_skip_nodes.delete(ast_node)
166
- end
167
- end
168
-
169
- def on_fragment_spread(ast_node, ast_parent)
170
- if @rewrite_skip_nodes.empty? && !skip?(ast_node)
171
- # Register the irep nodes that depend on this AST node:
172
- @rewrite_spread_parents[ast_node].merge(@rewrite_nodes_stack.last)
173
- @rewrite_spread_scopes[ast_node] = @rewrite_scopes_stack.last
174
- end
175
- super
176
- end
177
-
178
- def skip?(ast_node)
179
- dir = ast_node.directives
180
- dir.any? && !GraphQL::Execution::DirectiveChecks.include?(dir, @query)
181
- end
182
- end
183
- end
184
- end
@@ -1,88 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module InternalRepresentation
4
- # At a point in the AST, selections may apply to one or more types.
5
- # {Scope} represents those types which selections may apply to.
6
- #
7
- # Scopes can be defined by:
8
- #
9
- # - A single concrete or abstract type
10
- # - An array of types
11
- # - `nil`
12
- #
13
- # The AST may be scoped to an array of types when two abstractly-typed
14
- # fragments occur in inside one another.
15
- class Scope
16
- NO_TYPES = [].freeze
17
-
18
- # @param query [GraphQL::Query]
19
- # @param type_defn [GraphQL::BaseType, Array<GraphQL::BaseType>, nil]
20
- def initialize(query, type_defn)
21
- @query = query
22
- @type = type_defn
23
- @abstract_type = false
24
- @types = case type_defn
25
- when Array
26
- type_defn
27
- when GraphQL::BaseType
28
- @abstract_type = true
29
- nil
30
- when nil
31
- NO_TYPES
32
- else
33
- raise "Unexpected scope type: #{type_defn}"
34
- end
35
- end
36
-
37
- # From a starting point of `self`, create a new scope by condition `other_type_defn`.
38
- # @param other_type_defn [GraphQL::BaseType, nil]
39
- # @return [Scope]
40
- def enter(other_type_defn)
41
- case other_type_defn
42
- when nil
43
- # The type wasn't found, who cares
44
- Scope.new(@query, nil)
45
- when @type
46
- # The condition is the same as current, so reuse self
47
- self
48
- when GraphQL::UnionType, GraphQL::InterfaceType
49
- # Make a new scope of the intersection between the previous & next conditions
50
- new_types = @query.possible_types(other_type_defn) & concrete_types
51
- Scope.new(@query, new_types)
52
- when GraphQL::BaseType
53
- # If this type is valid within the current scope,
54
- # return a new scope of _exactly_ this type.
55
- # Otherwise, this type is out-of-scope so the scope is null.
56
- if concrete_types.include?(other_type_defn)
57
- Scope.new(@query, other_type_defn)
58
- else
59
- Scope.new(@query, nil)
60
- end
61
- else
62
- raise "Unexpected scope: #{other_type_defn.inspect}"
63
- end
64
- end
65
-
66
- # Call the block for each type in `self`.
67
- # This uses the simplest possible expression of `self`,
68
- # so if this scope is defined by an abstract type, it gets yielded.
69
- def each(&block)
70
- if @abstract_type
71
- yield(@type)
72
- else
73
- @types.each(&block)
74
- end
75
- end
76
-
77
- private
78
-
79
- def concrete_types
80
- @concrete_types ||= if @abstract_type
81
- @query.possible_types(@type)
82
- else
83
- @types
84
- end
85
- end
86
- end
87
- end
88
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module InternalRepresentation
4
- # Traverse a re-written query tree, calling handlers for each node
5
- module Visit
6
- module_function
7
- def visit_each_node(operations, handlers)
8
- return if handlers.empty?
9
- # Post-validation: make some assertions about the rewritten query tree
10
- operations.each do |op_name, op_node|
11
- # Yield each node to listeners which were attached by validators
12
- op_node.typed_children.each do |obj_type, children|
13
- children.each do |name, op_child_node|
14
- each_node(op_child_node) do |node|
15
- for h in handlers
16
- h.call(node)
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
23
-
24
- # Traverse a node in a rewritten query tree,
25
- # visiting the node itself and each of its typed children.
26
- def each_node(node, &block)
27
- yield(node)
28
- node.typed_children.each do |obj_type, children|
29
- children.each do |name, node|
30
- each_node(node, &block)
31
- end
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
- require "graphql/internal_representation/document"
3
- require "graphql/internal_representation/node"
4
- require "graphql/internal_representation/print"
5
- require "graphql/internal_representation/rewrite"
6
- require "graphql/internal_representation/scope"
7
- require "graphql/internal_representation/visit"