graphql 1.13.12 → 2.0.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (273) 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/trace.rb +96 -0
  14. data/lib/graphql/backtrace/tracer.rb +2 -3
  15. data/lib/graphql/backtrace.rb +7 -8
  16. data/lib/graphql/dataloader/null_dataloader.rb +3 -1
  17. data/lib/graphql/dataloader/source.rb +9 -0
  18. data/lib/graphql/dataloader.rb +4 -1
  19. data/lib/graphql/dig.rb +1 -1
  20. data/lib/graphql/execution/errors.rb +12 -82
  21. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  22. data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -3
  23. data/lib/graphql/execution/interpreter/resolve.rb +26 -0
  24. data/lib/graphql/execution/interpreter/runtime.rb +300 -222
  25. data/lib/graphql/execution/interpreter.rb +187 -78
  26. data/lib/graphql/execution/lazy.rb +7 -21
  27. data/lib/graphql/execution/lookahead.rb +44 -40
  28. data/lib/graphql/execution/multiplex.rb +3 -174
  29. data/lib/graphql/execution.rb +11 -4
  30. data/lib/graphql/filter.rb +7 -2
  31. data/lib/graphql/introspection/directive_type.rb +2 -2
  32. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  33. data/lib/graphql/introspection/entry_points.rb +2 -15
  34. data/lib/graphql/introspection/field_type.rb +1 -1
  35. data/lib/graphql/introspection/schema_type.rb +2 -2
  36. data/lib/graphql/introspection/type_type.rb +13 -6
  37. data/lib/graphql/introspection.rb +4 -3
  38. data/lib/graphql/language/document_from_schema_definition.rb +43 -44
  39. data/lib/graphql/language/lexer.rb +216 -1488
  40. data/lib/graphql/language/nodes.rb +66 -40
  41. data/lib/graphql/language/parser.rb +539 -510
  42. data/lib/graphql/language/parser.y +53 -44
  43. data/lib/graphql/language/printer.rb +37 -21
  44. data/lib/graphql/language/visitor.rb +191 -83
  45. data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
  46. data/lib/graphql/pagination/array_connection.rb +4 -2
  47. data/lib/graphql/pagination/connection.rb +33 -6
  48. data/lib/graphql/pagination/connections.rb +3 -28
  49. data/lib/graphql/pagination/relation_connection.rb +2 -0
  50. data/lib/graphql/query/context.rb +156 -196
  51. data/lib/graphql/query/input_validation_result.rb +10 -1
  52. data/lib/graphql/query/null_context.rb +1 -4
  53. data/lib/graphql/query/validation_pipeline.rb +12 -37
  54. data/lib/graphql/query/variable_validation_error.rb +2 -2
  55. data/lib/graphql/query/variables.rb +35 -21
  56. data/lib/graphql/query.rb +39 -46
  57. data/lib/graphql/railtie.rb +0 -104
  58. data/lib/graphql/rake_task/validate.rb +1 -1
  59. data/lib/graphql/rake_task.rb +29 -1
  60. data/lib/graphql/relay/range_add.rb +9 -20
  61. data/lib/graphql/relay.rb +0 -15
  62. data/lib/graphql/schema/addition.rb +7 -9
  63. data/lib/graphql/schema/argument.rb +38 -47
  64. data/lib/graphql/schema/build_from_definition.rb +47 -21
  65. data/lib/graphql/schema/directive/one_of.rb +12 -0
  66. data/lib/graphql/schema/directive/transform.rb +1 -1
  67. data/lib/graphql/schema/directive.rb +12 -23
  68. data/lib/graphql/schema/enum.rb +29 -41
  69. data/lib/graphql/schema/enum_value.rb +2 -25
  70. data/lib/graphql/schema/field/connection_extension.rb +4 -0
  71. data/lib/graphql/schema/field.rb +256 -349
  72. data/lib/graphql/schema/field_extension.rb +1 -4
  73. data/lib/graphql/schema/find_inherited_value.rb +2 -7
  74. data/lib/graphql/schema/input_object.rb +57 -69
  75. data/lib/graphql/schema/interface.rb +0 -35
  76. data/lib/graphql/schema/introspection_system.rb +3 -8
  77. data/lib/graphql/schema/late_bound_type.rb +8 -2
  78. data/lib/graphql/schema/list.rb +18 -9
  79. data/lib/graphql/schema/loader.rb +1 -2
  80. data/lib/graphql/schema/member/base_dsl_methods.rb +17 -19
  81. data/lib/graphql/schema/member/build_type.rb +5 -7
  82. data/lib/graphql/schema/member/has_arguments.rb +147 -56
  83. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  84. data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
  85. data/lib/graphql/schema/member/has_directives.rb +81 -61
  86. data/lib/graphql/schema/member/has_fields.rb +97 -40
  87. data/lib/graphql/schema/member/has_interfaces.rb +49 -10
  88. data/lib/graphql/schema/member/has_validators.rb +32 -6
  89. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  90. data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
  91. data/lib/graphql/schema/member/validates_input.rb +3 -3
  92. data/lib/graphql/schema/member.rb +0 -6
  93. data/lib/graphql/schema/mutation.rb +0 -9
  94. data/lib/graphql/schema/non_null.rb +3 -9
  95. data/lib/graphql/schema/object.rb +15 -52
  96. data/lib/graphql/schema/relay_classic_mutation.rb +53 -42
  97. data/lib/graphql/schema/resolver/has_payload_type.rb +20 -10
  98. data/lib/graphql/schema/resolver.rb +43 -44
  99. data/lib/graphql/schema/scalar.rb +8 -23
  100. data/lib/graphql/schema/subscription.rb +0 -7
  101. data/lib/graphql/schema/timeout.rb +24 -28
  102. data/lib/graphql/schema/type_membership.rb +3 -0
  103. data/lib/graphql/schema/union.rb +10 -17
  104. data/lib/graphql/schema/validator.rb +1 -1
  105. data/lib/graphql/schema/warden.rb +37 -9
  106. data/lib/graphql/schema/wrapper.rb +0 -5
  107. data/lib/graphql/schema.rb +265 -968
  108. data/lib/graphql/static_validation/all_rules.rb +1 -0
  109. data/lib/graphql/static_validation/base_visitor.rb +4 -21
  110. data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
  111. data/lib/graphql/static_validation/error.rb +2 -2
  112. data/lib/graphql/static_validation/literal_validator.rb +19 -1
  113. data/lib/graphql/static_validation/rules/directives_are_defined.rb +11 -5
  114. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
  115. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
  116. data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
  117. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  118. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  119. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +12 -6
  120. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
  121. data/lib/graphql/static_validation/validator.rb +3 -25
  122. data/lib/graphql/static_validation.rb +0 -2
  123. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -1
  124. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
  125. data/lib/graphql/subscriptions/event.rb +3 -8
  126. data/lib/graphql/subscriptions/instrumentation.rb +0 -51
  127. data/lib/graphql/subscriptions.rb +32 -20
  128. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  129. data/lib/graphql/tracing/appoptics_trace.rb +231 -0
  130. data/lib/graphql/tracing/appsignal_trace.rb +77 -0
  131. data/lib/graphql/tracing/data_dog_trace.rb +148 -0
  132. data/lib/graphql/tracing/data_dog_tracing.rb +21 -2
  133. data/lib/graphql/tracing/legacy_trace.rb +65 -0
  134. data/lib/graphql/tracing/new_relic_trace.rb +75 -0
  135. data/lib/graphql/tracing/notifications_trace.rb +42 -0
  136. data/lib/graphql/tracing/platform_trace.rb +109 -0
  137. data/lib/graphql/tracing/platform_tracing.rb +33 -43
  138. data/lib/graphql/tracing/prometheus_trace.rb +89 -0
  139. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +1 -1
  140. data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
  141. data/lib/graphql/tracing/scout_trace.rb +72 -0
  142. data/lib/graphql/tracing/statsd_trace.rb +56 -0
  143. data/lib/graphql/tracing/trace.rb +75 -0
  144. data/lib/graphql/tracing.rb +16 -40
  145. data/lib/graphql/type_kinds.rb +6 -3
  146. data/lib/graphql/types/iso_8601_date.rb +4 -1
  147. data/lib/graphql/types/iso_8601_date_time.rb +4 -0
  148. data/lib/graphql/types/relay/base_connection.rb +16 -6
  149. data/lib/graphql/types/relay/connection_behaviors.rb +29 -27
  150. data/lib/graphql/types/relay/edge_behaviors.rb +16 -5
  151. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  152. data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
  153. data/lib/graphql/types/relay.rb +0 -3
  154. data/lib/graphql/types/string.rb +1 -1
  155. data/lib/graphql/version.rb +1 -1
  156. data/lib/graphql.rb +17 -74
  157. metadata +33 -133
  158. data/lib/graphql/analysis/analyze_query.rb +0 -98
  159. data/lib/graphql/analysis/field_usage.rb +0 -45
  160. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  161. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  162. data/lib/graphql/analysis/query_complexity.rb +0 -88
  163. data/lib/graphql/analysis/query_depth.rb +0 -43
  164. data/lib/graphql/analysis/reducer_state.rb +0 -48
  165. data/lib/graphql/argument.rb +0 -131
  166. data/lib/graphql/authorization.rb +0 -82
  167. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  168. data/lib/graphql/backwards_compatibility.rb +0 -61
  169. data/lib/graphql/base_type.rb +0 -232
  170. data/lib/graphql/boolean_type.rb +0 -2
  171. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  172. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  173. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  174. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  175. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  176. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  177. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  178. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  179. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  180. data/lib/graphql/compatibility.rb +0 -5
  181. data/lib/graphql/define/assign_argument.rb +0 -12
  182. data/lib/graphql/define/assign_connection.rb +0 -13
  183. data/lib/graphql/define/assign_enum_value.rb +0 -18
  184. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  185. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  186. data/lib/graphql/define/assign_object_field.rb +0 -42
  187. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  188. data/lib/graphql/define/instance_definable.rb +0 -255
  189. data/lib/graphql/define/no_definition_error.rb +0 -7
  190. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  191. data/lib/graphql/define/type_definer.rb +0 -31
  192. data/lib/graphql/define.rb +0 -31
  193. data/lib/graphql/deprecated_dsl.rb +0 -55
  194. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  195. data/lib/graphql/directive/include_directive.rb +0 -2
  196. data/lib/graphql/directive/skip_directive.rb +0 -2
  197. data/lib/graphql/directive.rb +0 -107
  198. data/lib/graphql/enum_type.rb +0 -133
  199. data/lib/graphql/execution/execute.rb +0 -333
  200. data/lib/graphql/execution/flatten.rb +0 -40
  201. data/lib/graphql/execution/instrumentation.rb +0 -92
  202. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  203. data/lib/graphql/execution/typecast.rb +0 -50
  204. data/lib/graphql/field/resolve.rb +0 -59
  205. data/lib/graphql/field.rb +0 -226
  206. data/lib/graphql/float_type.rb +0 -2
  207. data/lib/graphql/function.rb +0 -128
  208. data/lib/graphql/id_type.rb +0 -2
  209. data/lib/graphql/input_object_type.rb +0 -138
  210. data/lib/graphql/int_type.rb +0 -2
  211. data/lib/graphql/interface_type.rb +0 -72
  212. data/lib/graphql/internal_representation/document.rb +0 -27
  213. data/lib/graphql/internal_representation/node.rb +0 -206
  214. data/lib/graphql/internal_representation/print.rb +0 -51
  215. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  216. data/lib/graphql/internal_representation/scope.rb +0 -88
  217. data/lib/graphql/internal_representation/visit.rb +0 -36
  218. data/lib/graphql/internal_representation.rb +0 -7
  219. data/lib/graphql/language/lexer.rl +0 -260
  220. data/lib/graphql/list_type.rb +0 -80
  221. data/lib/graphql/non_null_type.rb +0 -71
  222. data/lib/graphql/object_type.rb +0 -130
  223. data/lib/graphql/query/arguments.rb +0 -189
  224. data/lib/graphql/query/arguments_cache.rb +0 -24
  225. data/lib/graphql/query/executor.rb +0 -52
  226. data/lib/graphql/query/literal_input.rb +0 -136
  227. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  228. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  229. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  230. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  231. data/lib/graphql/query/serial_execution.rb +0 -40
  232. data/lib/graphql/relay/array_connection.rb +0 -83
  233. data/lib/graphql/relay/base_connection.rb +0 -189
  234. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  235. data/lib/graphql/relay/connection_resolve.rb +0 -43
  236. data/lib/graphql/relay/connection_type.rb +0 -54
  237. data/lib/graphql/relay/edge.rb +0 -27
  238. data/lib/graphql/relay/edge_type.rb +0 -19
  239. data/lib/graphql/relay/edges_instrumentation.rb +0 -39
  240. data/lib/graphql/relay/global_id_resolve.rb +0 -17
  241. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  242. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  243. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  244. data/lib/graphql/relay/mutation/result.rb +0 -38
  245. data/lib/graphql/relay/mutation.rb +0 -106
  246. data/lib/graphql/relay/node.rb +0 -39
  247. data/lib/graphql/relay/page_info.rb +0 -7
  248. data/lib/graphql/relay/relation_connection.rb +0 -188
  249. data/lib/graphql/relay/type_extensions.rb +0 -32
  250. data/lib/graphql/scalar_type.rb +0 -91
  251. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  252. data/lib/graphql/schema/default_parse_error.rb +0 -10
  253. data/lib/graphql/schema/default_type_error.rb +0 -17
  254. data/lib/graphql/schema/member/accepts_definition.rb +0 -164
  255. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
  256. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  257. data/lib/graphql/schema/middleware_chain.rb +0 -82
  258. data/lib/graphql/schema/possible_types.rb +0 -44
  259. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  260. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  261. data/lib/graphql/schema/traversal.rb +0 -228
  262. data/lib/graphql/schema/validation.rb +0 -313
  263. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  264. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  265. data/lib/graphql/string_type.rb +0 -2
  266. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  267. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  268. data/lib/graphql/types/relay/default_relay.rb +0 -31
  269. data/lib/graphql/types/relay/node_field.rb +0 -24
  270. data/lib/graphql/types/relay/nodes_field.rb +0 -43
  271. data/lib/graphql/union_type.rb +0 -115
  272. data/lib/graphql/upgrader/member.rb +0 -937
  273. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -1,164 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GraphQL
4
- class Schema
5
- class Member
6
- # Support for legacy `accepts_definitions` functions.
7
- #
8
- # Keep the legacy handler hooked up. Class-based types and fields
9
- # will call those legacy handlers during their `.to_graphql`
10
- # methods.
11
- #
12
- # This can help out while transitioning from one to the other.
13
- # Eventually, `GraphQL::{X}Type` objects will be removed entirely,
14
- # But this can help during the transition.
15
- #
16
- # @example Applying a function to base object class
17
- # # Here's the legacy-style config, which we're calling back to:
18
- # GraphQL::ObjectType.accepts_definition({
19
- # permission_level: ->(defn, value) { defn.metadata[:permission_level] = value }
20
- # })
21
- #
22
- # class BaseObject < GraphQL::Schema::Object
23
- # # Setup a named pass-through to the legacy config functions
24
- # accepts_definition :permission_level
25
- # end
26
- #
27
- # class Account < BaseObject
28
- # # This value will be passed to the legacy handler:
29
- # permission_level 1
30
- # end
31
- #
32
- # # The class gets a reader method which returns the args,
33
- # # only marginally useful.
34
- # Account.permission_level # => [1]
35
- #
36
- # # The legacy handler is called, as before:
37
- # Account.graphql_definition.metadata[:permission_level] # => 1
38
- module AcceptsDefinition
39
- def self.included(child)
40
- child.extend(AcceptsDefinitionDefinitionMethods)
41
- child.prepend(ToGraphQLExtension)
42
- child.prepend(InitializeExtension)
43
- end
44
-
45
- def self.extended(child)
46
- if defined?(child::DefinitionMethods)
47
- child::DefinitionMethods.include(AcceptsDefinitionDefinitionMethods)
48
- child::DefinitionMethods.prepend(ToGraphQLExtension)
49
- else
50
- child.extend(AcceptsDefinitionDefinitionMethods)
51
- # I tried to use `super`, but super isn't quite right
52
- # since the method is defined in the same class itself,
53
- # not the superclass
54
- child.class_eval do
55
- class << self
56
- prepend(ToGraphQLExtension)
57
- end
58
- end
59
- end
60
- end
61
-
62
- module AcceptsDefinitionDefinitionMethods
63
- def accepts_definition(name)
64
- own_accepts_definition_methods << name
65
-
66
- ivar_name = "@#{name}_args"
67
- if self.is_a?(Class)
68
- define_singleton_method(name) do |*args|
69
- if args.any?
70
- instance_variable_set(ivar_name, args)
71
- end
72
- instance_variable_get(ivar_name) || (superclass.respond_to?(name) ? superclass.public_send(name) : nil)
73
- end
74
-
75
- define_method(name) do |*args|
76
- if args.any?
77
- instance_variable_set(ivar_name, args)
78
- end
79
- instance_variable_get(ivar_name)
80
- end
81
- else
82
- # Special handling for interfaces, define it here
83
- # so it's appropriately passed down
84
- self::DefinitionMethods.module_eval do
85
- define_method(name) do |*args|
86
- if args.any?
87
- instance_variable_set(ivar_name, args)
88
- else
89
- if (v = instance_variable_get(ivar_name))
90
- v
91
- elsif (ancestor = ancestors.find { |i| i.respond_to?(name) && i != self })
92
- ancestor.public_send(name)
93
- else
94
- nil
95
- end
96
- end
97
- end
98
- end
99
- end
100
- end
101
-
102
- def accepts_definition_methods
103
- inherited_methods = if self.is_a?(Class)
104
- superclass.respond_to?(:accepts_definition_methods) ? superclass.accepts_definition_methods : []
105
- elsif self.is_a?(Module)
106
- m = []
107
- ancestors.each do |a|
108
- if a.respond_to?(:own_accepts_definition_methods)
109
- m.concat(a.own_accepts_definition_methods)
110
- end
111
- end
112
- m
113
- else
114
- self.class.accepts_definition_methods
115
- end
116
-
117
- own_accepts_definition_methods + inherited_methods
118
- end
119
-
120
- def own_accepts_definition_methods
121
- @own_accepts_definition_methods ||= []
122
- end
123
- end
124
-
125
- module ToGraphQLExtension
126
- def to_graphql(*args, **kwargs)
127
-
128
- defn = if args.empty? && kwargs.empty?
129
- super()
130
- else
131
- super
132
- end
133
- accepts_definition_methods.each do |method_name|
134
- value = public_send(method_name)
135
- if !value.nil?
136
- defn = defn.redefine { public_send(method_name, *value) }
137
- end
138
- end
139
- defn
140
- end
141
- end
142
-
143
- module InitializeExtension
144
- def initialize(*args, **kwargs, &block)
145
- self.class.accepts_definition_methods.each do |method_name|
146
- if kwargs.key?(method_name)
147
- value = kwargs.delete(method_name)
148
- if !value.is_a?(Array)
149
- value = [value]
150
- end
151
- instance_variable_set("@#{method_name}_args", value)
152
- end
153
- end
154
- super(*args, **kwargs, &block)
155
- end
156
-
157
- def accepts_definition_methods
158
- self.class.accepts_definition_methods
159
- end
160
- end
161
- end
162
- end
163
- end
164
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GraphQL
4
- class Schema
5
- class Member
6
- # Adds a layer of caching over user-supplied `.to_graphql` methods.
7
- # Users override `.to_graphql`, but all runtime code should use `.graphql_definition`.
8
- # @api private
9
- # @see concrete classes that extend this, eg {Schema::Object}
10
- module CachedGraphQLDefinition
11
- # A cached result of {.to_graphql}.
12
- # It's cached here so that user-overridden {.to_graphql} implementations
13
- # are also cached
14
- def graphql_definition(silence_deprecation_warning: false)
15
- @graphql_definition ||= begin
16
- unless silence_deprecation_warning
17
- message = "Legacy `.graphql_definition` objects are deprecated and will be removed in GraphQL-Ruby 2.0. Remove `.graphql_definition` to use a class-based definition instead."
18
- caller_message = "\n\nCalled on #{self.inspect} from:\n #{caller(1, 25).map { |l| " #{l}" }.join("\n")}"
19
- GraphQL::Deprecation.warn(message + caller_message)
20
- end
21
- deprecated_to_graphql
22
- end
23
- end
24
-
25
- def deprecated_to_graphql
26
- case method(:to_graphql).arity
27
- when 0
28
- to_graphql
29
- else
30
- to_graphql(silence_deprecation_warning: true)
31
- end
32
- end
33
-
34
- # This is for a common interface with .define-based types
35
- def type_class
36
- self
37
- end
38
-
39
- # Wipe out the cached graphql_definition so that `.to_graphql` will be called again.
40
- def initialize_copy(original)
41
- super
42
- @graphql_definition = nil
43
- end
44
-
45
- module DeprecatedToGraphQL
46
- def to_graphql(silence_deprecation_warning: false)
47
- unless silence_deprecation_warning
48
- message = "Legacy `.to_graphql` objects are deprecated and will be removed in GraphQL-Ruby 2.0. Remove `.to_graphql` to use a class-based definition instead."
49
- caller_message = "\n\nCalled on #{self.inspect} from:\n #{caller(1, 25).map { |l| " #{l}" }.join("\n")}"
50
- GraphQL::Deprecation.warn(message + caller_message)
51
- end
52
- super()
53
- end
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,131 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GraphQL
4
- class Schema
5
- class Member
6
- module Instrumentation
7
- module_function
8
- def instrument(type, field)
9
- return_type = field.type.unwrap
10
- if (return_type.is_a?(GraphQL::ObjectType) && return_type.metadata[:type_class]) ||
11
- return_type.is_a?(GraphQL::InterfaceType) ||
12
- (return_type.is_a?(GraphQL::UnionType) && return_type.possible_types.any? { |t| t.metadata[:type_class] })
13
- field = apply_proxy(field)
14
- end
15
-
16
- field
17
- end
18
-
19
- def before_query(query)
20
- # Get the root type for this query
21
- root_node = query.irep_selection
22
- if root_node.nil?
23
- # It's an invalid query, nothing to do here
24
- else
25
- root_type = query.irep_selection.return_type
26
- # If it has a wrapper, apply it
27
- wrapper_class = root_type.metadata[:type_class]
28
- if wrapper_class
29
- new_root_value = wrapper_class.authorized_new(query.root_value, query.context)
30
- new_root_value = query.schema.sync_lazy(new_root_value)
31
- if new_root_value.nil?
32
- # This is definitely a hack,
33
- # but we need some way to tell execute.rb not to run.
34
- query.context[:__root_unauthorized] = true
35
- end
36
- query.root_value = new_root_value
37
- end
38
- end
39
- end
40
-
41
- def after_query(_query)
42
- end
43
-
44
- private
45
-
46
- module_function
47
-
48
- def apply_proxy(field)
49
- resolve_proc = field.resolve_proc
50
- lazy_resolve_proc = field.lazy_resolve_proc
51
- inner_return_type = field.type.unwrap
52
- depth = list_depth(field.type)
53
-
54
- field.redefine(
55
- resolve: ProxiedResolve.new(inner_resolve: resolve_proc, list_depth: depth, inner_return_type: inner_return_type),
56
- lazy_resolve: ProxiedResolve.new(inner_resolve: lazy_resolve_proc, list_depth: depth, inner_return_type: inner_return_type),
57
- )
58
- end
59
-
60
- def list_depth(type, starting_at = 0)
61
- case type
62
- when GraphQL::ListType
63
- list_depth(type.of_type, starting_at + 1)
64
- when GraphQL::NonNullType
65
- list_depth(type.of_type, starting_at)
66
- else
67
- starting_at
68
- end
69
- end
70
-
71
- class ProxiedResolve
72
- def initialize(inner_resolve:, list_depth:, inner_return_type:)
73
- @inner_resolve = inner_resolve
74
- @inner_return_type = inner_return_type
75
- @list_depth = list_depth
76
- end
77
-
78
- def call(obj, args, ctx)
79
- result = @inner_resolve.call(obj, args, ctx)
80
- if ctx.skip == result || ctx.schema.lazy?(result) || result.nil? || execution_errors?(result) || ctx.wrapped_object
81
- result
82
- else
83
- ctx.wrapped_object = true
84
- proxy_to_depth(result, @list_depth, ctx)
85
- end
86
- end
87
-
88
- private
89
-
90
- def execution_errors?(result)
91
- result.is_a?(GraphQL::ExecutionError) ||
92
- (result.is_a?(Array) && result.any? && result.all? { |v| v.is_a?(GraphQL::ExecutionError) })
93
- end
94
-
95
- def proxy_to_depth(inner_obj, depth, ctx)
96
- if depth > 0
97
- inner_obj.map { |i| proxy_to_depth(i, depth - 1, ctx) }
98
- else
99
- ctx.schema.after_lazy(inner_obj) do |inner_obj|
100
- if inner_obj.nil?
101
- # For lists with nil, we need another nil check here
102
- nil
103
- else
104
- concrete_type_or_lazy = case @inner_return_type
105
- when GraphQL::UnionType, GraphQL::InterfaceType
106
- ctx.query.resolve_type(@inner_return_type, inner_obj)
107
- when GraphQL::ObjectType
108
- @inner_return_type
109
- else
110
- raise "unexpected proxying type #{@inner_return_type} for #{inner_obj} at #{ctx.owner_type}.#{ctx.field.name}"
111
- end
112
-
113
- # .resolve_type may have returned a lazy
114
- ctx.schema.after_lazy(concrete_type_or_lazy) do |concrete_type|
115
- if concrete_type && (object_class = concrete_type.metadata[:type_class])
116
- # use the query-level context here, since it won't be field-specific anyways
117
- query_ctx = ctx.query.context
118
- object_class.authorized_new(inner_obj, query_ctx)
119
- else
120
- inner_obj
121
- end
122
- end
123
- end
124
- end
125
- end
126
- end
127
- end
128
- end
129
- end
130
- end
131
- end
@@ -1,82 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- class Schema
4
- # Given {steps} and {arguments}, call steps in order, passing `(*arguments, next_step)`.
5
- #
6
- # Steps should call `next_step.call` to continue the chain, or _not_ call it to stop the chain.
7
- class MiddlewareChain
8
- extend Forwardable
9
-
10
- # @return [Array<#call(*args)>] Steps in this chain, will be called with arguments and `next_middleware`
11
- attr_reader :steps, :final_step
12
-
13
- def initialize(steps: [], final_step: nil)
14
- @steps = steps
15
- @final_step = final_step
16
- end
17
-
18
- def initialize_copy(other)
19
- super
20
- @steps = other.steps.dup
21
- end
22
-
23
- def_delegators :@steps, :[], :first, :insert, :delete
24
-
25
- def <<(callable)
26
- add_middleware(callable)
27
- end
28
-
29
- def push(callable)
30
- add_middleware(callable)
31
- end
32
-
33
- def ==(other)
34
- steps == other.steps && final_step == other.final_step
35
- end
36
-
37
- def invoke(arguments)
38
- invoke_core(0, arguments)
39
- end
40
-
41
- def concat(callables)
42
- callables.each { |c| add_middleware(c) }
43
- end
44
-
45
- private
46
-
47
- def invoke_core(index, arguments)
48
- if index >= steps.length
49
- final_step.call(*arguments)
50
- else
51
- steps[index].call(*arguments) { |next_args = arguments| invoke_core(index + 1, next_args) }
52
- end
53
- end
54
-
55
- def add_middleware(callable)
56
- # TODO: Stop wrapping callables once deprecated middleware becomes unsupported
57
- steps << wrap(callable)
58
- end
59
-
60
- # TODO: Remove this code once deprecated middleware becomes unsupported
61
- class MiddlewareWrapper
62
- attr_reader :callable
63
- def initialize(callable)
64
- @callable = callable
65
- end
66
-
67
- def call(*args, &next_middleware)
68
- callable.call(*args, next_middleware)
69
- end
70
- end
71
-
72
- def wrap(callable)
73
- if BackwardsCompatibility.get_arity(callable) == 6
74
- GraphQL::Deprecation.warn("Middleware that takes a next_middleware parameter is deprecated (#{callable.inspect}); instead, accept a block and use yield.")
75
- MiddlewareWrapper.new(callable)
76
- else
77
- callable
78
- end
79
- end
80
- end
81
- end
82
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- class Schema
4
- # Find the members of a union or interface within a given schema.
5
- #
6
- # (Although its members never change, unions are handled this way to simplify execution code.)
7
- #
8
- # Internally, the calculation is cached. It's assumed that schema members _don't_ change after creating the schema!
9
- #
10
- # @example Get an interface's possible types
11
- # possible_types = GraphQL::Schema::PossibleTypes(MySchema)
12
- # possible_types.possible_types(MyInterface)
13
- # # => [MyObjectType, MyOtherObjectType]
14
- class PossibleTypes
15
- def initialize(schema)
16
- @object_types = schema.types.values.select { |type| type.kind.object? }
17
- @interface_implementers = Hash.new do |h1, ctx|
18
- h1[ctx] = Hash.new do |h2, int_type|
19
- h2[int_type] = @object_types.select { |type| type.interfaces(ctx).include?(int_type) }.sort_by(&:name)
20
- end
21
- end
22
- end
23
-
24
- def possible_types(type_defn, ctx)
25
- case type_defn
26
- when Module
27
- possible_types(type_defn.graphql_definition, ctx)
28
- when GraphQL::UnionType
29
- type_defn.possible_types(ctx)
30
- when GraphQL::InterfaceType
31
- interface_implementers(ctx, type_defn)
32
- when GraphQL::BaseType
33
- [type_defn]
34
- else
35
- raise "Unexpected possible_types object: #{type_defn.inspect}"
36
- end
37
- end
38
-
39
- def interface_implementers(ctx, type_defn)
40
- @interface_implementers[ctx][type_defn]
41
- end
42
- end
43
- end
44
- end
@@ -1,60 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- class Schema
4
- # - Store a table of errors & handlers
5
- # - Rescue errors in a middleware chain, then check for a handler
6
- # - If a handler is found, use it & return a {GraphQL::ExecutionError}
7
- # - If no handler is found, re-raise the error
8
- class RescueMiddleware
9
- # @return [Hash] `{class => proc}` pairs for handling errors
10
- attr_reader :rescue_table
11
- def initialize
12
- @rescue_table = {}
13
- end
14
-
15
- # @example Rescue from not-found by telling the user
16
- # MySchema.rescue_from(ActiveRecord::RecordNotFound) { "An item could not be found" }
17
- #
18
- # @param error_classes [Class] one or more classes of errors to rescue from
19
- # @yield [err] A handler to return a message for these error instances
20
- # @yieldparam [Exception] an error that was rescued
21
- # @yieldreturn [String] message to put in GraphQL response
22
- def rescue_from(*error_classes, &block)
23
- error_classes.map{ |error_class| rescue_table[error_class] = block }
24
- end
25
-
26
- # Remove the handler for `error_classs`
27
- # @param error_class [Class] the error class whose handler should be removed
28
- def remove_handler(*error_classes)
29
- error_classes.map{ |error_class| rescue_table.delete(error_class) }
30
- end
31
-
32
- # Implement the requirement for {GraphQL::Schema::MiddlewareChain}
33
- def call(*args)
34
- begin
35
- yield
36
- rescue StandardError => err
37
- attempt_rescue(err)
38
- end
39
- end
40
-
41
- private
42
-
43
- def attempt_rescue(err)
44
- rescue_table.each { |klass, handler|
45
- if klass.is_a?(Class) && err.is_a?(klass) && handler
46
- result = handler.call(err)
47
- case result
48
- when String
49
- return GraphQL::ExecutionError.new(result)
50
- when GraphQL::ExecutionError
51
- return result
52
- end
53
- end
54
- }
55
-
56
- raise(err)
57
- end
58
- end
59
- end
60
- end
@@ -1,88 +0,0 @@
1
- # frozen_string_literal: true
2
- require "delegate"
3
-
4
- module GraphQL
5
- class Schema
6
- # This middleware will stop resolving new fields after `max_seconds` have elapsed.
7
- # After the time has passed, any remaining fields will be `nil`, with errors added
8
- # to the `errors` key. Any already-resolved fields will be in the `data` key, so
9
- # you'll get a partial response.
10
- #
11
- # You can provide a block which will be called with any timeout errors that occur.
12
- #
13
- # Note that this will stop a query _in between_ field resolutions, but
14
- # it doesn't interrupt long-running `resolve` functions. Be sure to use
15
- # timeout options for external connections. For more info, see
16
- # www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/
17
- #
18
- # @example Stop resolving fields after 2 seconds
19
- # MySchema.middleware << GraphQL::Schema::TimeoutMiddleware.new(max_seconds: 2)
20
- #
21
- # @example Notifying Bugsnag on a timeout
22
- # MySchema.middleware << GraphQL::Schema::TimeoutMiddleware(max_seconds: 1.5) do |timeout_error, query|
23
- # Bugsnag.notify(timeout_error, {query_string: query_ctx.query.query_string})
24
- # end
25
- #
26
- # @api deprecated
27
- # @see Schema::Timeout
28
- class TimeoutMiddleware
29
- # @param max_seconds [Numeric] how many seconds the query should be allowed to resolve new fields
30
- def initialize(max_seconds:, context_key: nil, &block)
31
- @max_seconds = max_seconds
32
- if context_key
33
- GraphQL::Deprecation.warn("TimeoutMiddleware's `context_key` is ignored, timeout data is now stored in isolated storage")
34
- end
35
- @error_handler = block
36
- end
37
-
38
- def call(parent_type, parent_object, field_definition, field_args, query_context)
39
- ns = query_context.namespace(self.class)
40
- now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
41
- timeout_at = ns[:timeout_at] ||= now + @max_seconds
42
-
43
- if timeout_at < now
44
- on_timeout(parent_type, parent_object, field_definition, field_args, query_context)
45
- else
46
- yield
47
- end
48
- end
49
-
50
- # This is called when a field _would_ be resolved, except that we're over the time limit.
51
- # @return [GraphQL::Schema::TimeoutMiddleware::TimeoutError] An error whose message will be added to the `errors` key
52
- def on_timeout(parent_type, parent_object, field_definition, field_args, field_context)
53
- err = GraphQL::Schema::TimeoutMiddleware::TimeoutError.new(parent_type, field_definition)
54
- if @error_handler
55
- query_proxy = TimeoutQueryProxy.new(field_context.query, field_context)
56
- @error_handler.call(err, query_proxy)
57
- end
58
- err
59
- end
60
-
61
- # This behaves like {GraphQL::Query} but {#context} returns
62
- # the _field-level_ context, not the query-level context.
63
- # This means you can reliably get the `irep_node` and `path`
64
- # from it after the fact.
65
- class TimeoutQueryProxy < SimpleDelegator
66
- def initialize(query, ctx)
67
- @context = ctx
68
- super(query)
69
- end
70
-
71
- attr_reader :context
72
- end
73
-
74
- # This error is raised when a query exceeds `max_seconds`.
75
- # Since it's a child of {GraphQL::ExecutionError},
76
- # its message will be added to the response's `errors` key.
77
- #
78
- # To raise an error that will stop query resolution, use a custom block
79
- # to take this error and raise a new one which _doesn't_ descend from {GraphQL::ExecutionError},
80
- # such as `RuntimeError`.
81
- class TimeoutError < GraphQL::ExecutionError
82
- def initialize(parent_type, field_defn)
83
- super("Timeout on #{parent_type.name}.#{field_defn.name}")
84
- end
85
- end
86
- end
87
- end
88
- end