graphql 2.0.27 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
  3. data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
  4. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  5. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  6. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  7. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  8. data/lib/generators/graphql/templates/base_field.erb +2 -0
  9. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  10. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  11. data/lib/generators/graphql/templates/base_object.erb +2 -0
  12. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  13. data/lib/generators/graphql/templates/base_union.erb +2 -0
  14. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  15. data/lib/generators/graphql/templates/loader.erb +2 -0
  16. data/lib/generators/graphql/templates/mutation.erb +2 -0
  17. data/lib/generators/graphql/templates/node_type.erb +2 -0
  18. data/lib/generators/graphql/templates/query_type.erb +2 -0
  19. data/lib/generators/graphql/templates/schema.erb +2 -0
  20. data/lib/graphql/analysis/ast/analyzer.rb +7 -0
  21. data/lib/graphql/analysis/ast/visitor.rb +2 -2
  22. data/lib/graphql/analysis/ast.rb +15 -11
  23. data/lib/graphql/dataloader/source.rb +7 -0
  24. data/lib/graphql/dataloader.rb +9 -0
  25. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +170 -0
  26. data/lib/graphql/execution/interpreter/runtime.rb +95 -254
  27. data/lib/graphql/execution/interpreter.rb +0 -6
  28. data/lib/graphql/execution/lookahead.rb +1 -1
  29. data/lib/graphql/introspection/dynamic_fields.rb +1 -1
  30. data/lib/graphql/introspection/entry_points.rb +2 -2
  31. data/lib/graphql/language/block_string.rb +28 -16
  32. data/lib/graphql/language/definition_slice.rb +1 -1
  33. data/lib/graphql/language/document_from_schema_definition.rb +36 -35
  34. data/lib/graphql/language/nodes.rb +2 -2
  35. data/lib/graphql/language/printer.rb +294 -145
  36. data/lib/graphql/language/sanitized_printer.rb +20 -22
  37. data/lib/graphql/language/static_visitor.rb +167 -0
  38. data/lib/graphql/language/visitor.rb +20 -81
  39. data/lib/graphql/language.rb +1 -0
  40. data/lib/graphql/pagination/connection.rb +23 -1
  41. data/lib/graphql/query/context/scoped_context.rb +101 -0
  42. data/lib/graphql/query/context.rb +32 -98
  43. data/lib/graphql/query.rb +2 -19
  44. data/lib/graphql/rake_task.rb +3 -12
  45. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  46. data/lib/graphql/schema/field/connection_extension.rb +1 -15
  47. data/lib/graphql/schema/field/scope_extension.rb +7 -1
  48. data/lib/graphql/schema/field.rb +6 -3
  49. data/lib/graphql/schema/has_single_input_argument.rb +156 -0
  50. data/lib/graphql/schema/introspection_system.rb +2 -0
  51. data/lib/graphql/schema/member/base_dsl_methods.rb +2 -1
  52. data/lib/graphql/schema/member/has_arguments.rb +14 -2
  53. data/lib/graphql/schema/member/has_fields.rb +4 -1
  54. data/lib/graphql/schema/member/has_interfaces.rb +21 -7
  55. data/lib/graphql/schema/member/scoped.rb +19 -0
  56. data/lib/graphql/schema/object.rb +8 -0
  57. data/lib/graphql/schema/printer.rb +8 -7
  58. data/lib/graphql/schema/relay_classic_mutation.rb +6 -128
  59. data/lib/graphql/schema/resolver.rb +4 -0
  60. data/lib/graphql/schema/scalar.rb +3 -3
  61. data/lib/graphql/schema/subscription.rb +11 -4
  62. data/lib/graphql/schema/warden.rb +23 -37
  63. data/lib/graphql/schema.rb +23 -22
  64. data/lib/graphql/static_validation/all_rules.rb +1 -1
  65. data/lib/graphql/static_validation/base_visitor.rb +1 -1
  66. data/lib/graphql/static_validation/literal_validator.rb +1 -1
  67. data/lib/graphql/static_validation/rules/fields_will_merge.rb +1 -1
  68. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
  69. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +1 -1
  70. data/lib/graphql/static_validation/validation_context.rb +5 -5
  71. data/lib/graphql/static_validation.rb +0 -1
  72. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +2 -1
  73. data/lib/graphql/subscriptions.rb +11 -6
  74. data/lib/graphql/tracing/appoptics_trace.rb +2 -2
  75. data/lib/graphql/tracing/appoptics_tracing.rb +2 -2
  76. data/lib/graphql/types/relay/connection_behaviors.rb +19 -2
  77. data/lib/graphql/types/relay/edge_behaviors.rb +7 -0
  78. data/lib/graphql/version.rb +1 -1
  79. data/lib/graphql.rb +1 -2
  80. metadata +7 -4
  81. data/lib/graphql/filter.rb +0 -59
  82. data/lib/graphql/static_validation/type_stack.rb +0 -216
@@ -67,9 +67,8 @@ module GraphQL
67
67
  type: [edge_type_class, null: edge_nullable],
68
68
  null: edges_nullable,
69
69
  description: "A list of edges.",
70
+ scope: false, # Assume that the connection was already scoped.
70
71
  connection: false,
71
- # Assume that the connection was scoped before this step:
72
- scope: false,
73
72
  }
74
73
 
75
74
  if field_options
@@ -170,6 +169,24 @@ module GraphQL
170
169
  obj_type.field :page_info, GraphQL::Types::Relay::PageInfo, null: false, description: "Information to aid in pagination."
171
170
  end
172
171
  end
172
+
173
+ def edges
174
+ # Assume that whatever authorization needed to happen
175
+ # already happened at the connection level.
176
+ current_runtime_state = Thread.current[:__graphql_runtime_info]
177
+ query_runtime_state = current_runtime_state[context.query]
178
+ query_runtime_state.was_authorized_by_scope_items = @object.was_authorized_by_scope_items?
179
+ @object.edges
180
+ end
181
+
182
+ def nodes
183
+ # Assume that whatever authorization needed to happen
184
+ # already happened at the connection level.
185
+ current_runtime_state = Thread.current[:__graphql_runtime_info]
186
+ query_runtime_state = current_runtime_state[context.query]
187
+ query_runtime_state.was_authorized_by_scope_items = @object.was_authorized_by_scope_items?
188
+ @object.nodes
189
+ end
173
190
  end
174
191
  end
175
192
  end
@@ -12,6 +12,13 @@ module GraphQL
12
12
  child_class.node_nullable(true)
13
13
  end
14
14
 
15
+ def node
16
+ current_runtime_state = Thread.current[:__graphql_runtime_info]
17
+ query_runtime_state = current_runtime_state[context.query]
18
+ query_runtime_state.was_authorized_by_scope_items = @object.was_authorized_by_scope_items?
19
+ @object.node
20
+ end
21
+
15
22
  module ClassMethods
16
23
  def inherited(child_class)
17
24
  super
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "2.0.27"
3
+ VERSION = "2.1.1"
4
4
  end
data/lib/graphql.rb CHANGED
@@ -101,9 +101,8 @@ require "graphql/execution"
101
101
  require "graphql/pagination"
102
102
  require "graphql/schema"
103
103
  require "graphql/query"
104
- require "graphql/types"
105
104
  require "graphql/dataloader"
106
- require "graphql/filter"
105
+ require "graphql/types"
107
106
  require "graphql/static_validation"
108
107
  require "graphql/execution"
109
108
  require "graphql/schema/built_in_types"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.27
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-30 00:00:00.000000000 Z
11
+ date: 2023-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips
@@ -326,12 +326,12 @@ files:
326
326
  - lib/graphql/execution/interpreter/handles_raw_value.rb
327
327
  - lib/graphql/execution/interpreter/resolve.rb
328
328
  - lib/graphql/execution/interpreter/runtime.rb
329
+ - lib/graphql/execution/interpreter/runtime/graphql_result.rb
329
330
  - lib/graphql/execution/lazy.rb
330
331
  - lib/graphql/execution/lazy/lazy_method_map.rb
331
332
  - lib/graphql/execution/lookahead.rb
332
333
  - lib/graphql/execution/multiplex.rb
333
334
  - lib/graphql/execution_error.rb
334
- - lib/graphql/filter.rb
335
335
  - lib/graphql/integer_decoding_error.rb
336
336
  - lib/graphql/integer_encoding_error.rb
337
337
  - lib/graphql/introspection.rb
@@ -361,6 +361,7 @@ files:
361
361
  - lib/graphql/language/parser.y
362
362
  - lib/graphql/language/printer.rb
363
363
  - lib/graphql/language/sanitized_printer.rb
364
+ - lib/graphql/language/static_visitor.rb
364
365
  - lib/graphql/language/token.rb
365
366
  - lib/graphql/language/visitor.rb
366
367
  - lib/graphql/load_application_object_failed_error.rb
@@ -376,6 +377,7 @@ files:
376
377
  - lib/graphql/parse_error.rb
377
378
  - lib/graphql/query.rb
378
379
  - lib/graphql/query/context.rb
380
+ - lib/graphql/query/context/scoped_context.rb
379
381
  - lib/graphql/query/fingerprint.rb
380
382
  - lib/graphql/query/input_validation_result.rb
381
383
  - lib/graphql/query/null_context.rb
@@ -410,6 +412,7 @@ files:
410
412
  - lib/graphql/schema/directive/include.rb
411
413
  - lib/graphql/schema/directive/one_of.rb
412
414
  - lib/graphql/schema/directive/skip.rb
415
+ - lib/graphql/schema/directive/specified_by.rb
413
416
  - lib/graphql/schema/directive/transform.rb
414
417
  - lib/graphql/schema/enum.rb
415
418
  - lib/graphql/schema/enum_value.rb
@@ -419,6 +422,7 @@ files:
419
422
  - lib/graphql/schema/field_extension.rb
420
423
  - lib/graphql/schema/find_inherited_value.rb
421
424
  - lib/graphql/schema/finder.rb
425
+ - lib/graphql/schema/has_single_input_argument.rb
422
426
  - lib/graphql/schema/input_object.rb
423
427
  - lib/graphql/schema/interface.rb
424
428
  - lib/graphql/schema/introspection_system.rb
@@ -536,7 +540,6 @@ files:
536
540
  - lib/graphql/static_validation/rules/variables_are_input_types_error.rb
537
541
  - lib/graphql/static_validation/rules/variables_are_used_and_defined.rb
538
542
  - lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb
539
- - lib/graphql/static_validation/type_stack.rb
540
543
  - lib/graphql/static_validation/validation_context.rb
541
544
  - lib/graphql/static_validation/validation_timeout_error.rb
542
545
  - lib/graphql/static_validation/validator.rb
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
- require "graphql/deprecation"
3
-
4
- module GraphQL
5
- # @api private
6
- class Filter
7
- def initialize(only: nil, except: nil, silence_deprecation_warning: false)
8
- if !silence_deprecation_warning
9
- line = caller(2, 10).find { |l| !l.include?("lib/graphql") }
10
- GraphQL::Deprecation.warn("GraphQL::Filter, `only:`, `except:`, and `.merge_filters` are deprecated and will be removed in v2.1.0. Implement `visible?` on your schema members instead (https://graphql-ruby.org/authorization/visibility.html).\n #{line}")
11
- end
12
- @only = only
13
- @except = except
14
- end
15
-
16
- # Returns true if `member, ctx` passes this filter
17
- def call(member, ctx)
18
- (@only ? @only.call(member, ctx) : true) &&
19
- (@except ? !@except.call(member, ctx) : true)
20
- end
21
-
22
- def merge(only: nil, except: nil)
23
- onlies = [self].concat(Array(only))
24
- merged_only = MergedOnly.build(onlies)
25
- merged_except = MergedExcept.build(Array(except))
26
- self.class.new(only: merged_only, except: merged_except, silence_deprecation_warning: true)
27
- end
28
-
29
- private
30
-
31
- class MergedOnly
32
- def initialize(first, second)
33
- @first = first
34
- @second = second
35
- end
36
-
37
- def call(member, ctx)
38
- @first.call(member, ctx) && @second.call(member, ctx)
39
- end
40
-
41
- def self.build(onlies)
42
- case onlies.size
43
- when 0
44
- nil
45
- when 1
46
- onlies[0]
47
- else
48
- onlies.reduce { |memo, only| self.new(memo, only) }
49
- end
50
- end
51
- end
52
-
53
- class MergedExcept < MergedOnly
54
- def call(member, ctx)
55
- @first.call(member, ctx) || @second.call(member, ctx)
56
- end
57
- end
58
- end
59
- end
@@ -1,216 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module StaticValidation
4
- # - Ride along with `GraphQL::Language::Visitor`
5
- # - Track type info, expose it to validators
6
- class TypeStack
7
- # These are jumping-off points for infering types down the tree
8
- TYPE_INFERRENCE_ROOTS = [
9
- GraphQL::Language::Nodes::OperationDefinition,
10
- GraphQL::Language::Nodes::FragmentDefinition,
11
- ]
12
-
13
- # @return [GraphQL::Schema] the schema whose types are present in this document
14
- attr_reader :schema
15
-
16
- # When it enters an object (starting with query or mutation root), it's pushed on this stack.
17
- # When it exits, it's popped off.
18
- # @return [Array<GraphQL::ObjectType, GraphQL::Union, GraphQL::Interface>]
19
- attr_reader :object_types
20
-
21
- # When it enters a field, it's pushed on this stack (useful for nested fields, args).
22
- # When it exits, it's popped off.
23
- # @return [Array<GraphQL::Field>] fields which have been entered
24
- attr_reader :field_definitions
25
-
26
- # Directives are pushed on, then popped off while traversing the tree
27
- # @return [Array<GraphQL::Node::Directive>] directives which have been entered
28
- attr_reader :directive_definitions
29
-
30
- # @return [Array<GraphQL::Node::Argument>] arguments which have been entered
31
- attr_reader :argument_definitions
32
-
33
- # @return [Array<String>] fields which have been entered (by their AST name)
34
- attr_reader :path
35
-
36
- # @param schema [GraphQL::Schema] the schema whose types to use when climbing this document
37
- # @param visitor [GraphQL::Language::Visitor] a visitor to follow & watch the types
38
- def initialize(schema, visitor)
39
- @schema = schema
40
- @object_types = []
41
- @field_definitions = []
42
- @directive_definitions = []
43
- @argument_definitions = []
44
- @path = []
45
-
46
- PUSH_STRATEGIES.each do |node_class, strategy|
47
- visitor[node_class].enter << EnterWithStrategy.new(self, strategy)
48
- visitor[node_class].leave << LeaveWithStrategy.new(self, strategy)
49
- end
50
- end
51
-
52
- private
53
-
54
-
55
- module FragmentWithTypeStrategy
56
- def push(stack, node)
57
- object_type = if node.type
58
- stack.schema.get_type(node.type.name)
59
- else
60
- stack.object_types.last
61
- end
62
- if !object_type.nil?
63
- object_type = object_type.unwrap
64
- end
65
- stack.object_types.push(object_type)
66
- push_path_member(stack, node)
67
- end
68
-
69
- def pop(stack, node)
70
- stack.object_types.pop
71
- stack.path.pop
72
- end
73
- end
74
-
75
- module FragmentDefinitionStrategy
76
- extend FragmentWithTypeStrategy
77
- module_function
78
- def push_path_member(stack, node)
79
- stack.path.push("fragment #{node.name}")
80
- end
81
- end
82
-
83
- module InlineFragmentStrategy
84
- extend FragmentWithTypeStrategy
85
- module_function
86
- def push_path_member(stack, node)
87
- stack.path.push("...#{node.type ? " on #{node.type.to_query_string}" : ""}")
88
- end
89
- end
90
-
91
- module OperationDefinitionStrategy
92
- module_function
93
- def push(stack, node)
94
- # eg, QueryType, MutationType
95
- object_type = stack.schema.root_type_for_operation(node.operation_type)
96
- stack.object_types.push(object_type)
97
- stack.path.push("#{node.operation_type}#{node.name ? " #{node.name}" : ""}")
98
- end
99
-
100
- def pop(stack, node)
101
- stack.object_types.pop
102
- stack.path.pop
103
- end
104
- end
105
-
106
- module FieldStrategy
107
- module_function
108
- def push(stack, node)
109
- parent_type = stack.object_types.last
110
- parent_type = parent_type.unwrap
111
-
112
- field_definition = stack.schema.get_field(parent_type, node.name)
113
- stack.field_definitions.push(field_definition)
114
- if !field_definition.nil?
115
- next_object_type = field_definition.type
116
- stack.object_types.push(next_object_type)
117
- else
118
- stack.object_types.push(nil)
119
- end
120
- stack.path.push(node.alias || node.name)
121
- end
122
-
123
- def pop(stack, node)
124
- stack.field_definitions.pop
125
- stack.object_types.pop
126
- stack.path.pop
127
- end
128
- end
129
-
130
- module DirectiveStrategy
131
- module_function
132
- def push(stack, node)
133
- directive_defn = stack.schema.directives[node.name]
134
- stack.directive_definitions.push(directive_defn)
135
- end
136
-
137
- def pop(stack, node)
138
- stack.directive_definitions.pop
139
- end
140
- end
141
-
142
- module ArgumentStrategy
143
- module_function
144
- # Push `argument_defn` onto the stack.
145
- # It's possible that `argument_defn` will be nil.
146
- # Push it anyways so `pop` has something to pop.
147
- def push(stack, node)
148
- if stack.argument_definitions.last
149
- arg_type = stack.argument_definitions.last.type.unwrap
150
- if arg_type.kind.input_object?
151
- argument_defn = arg_type.arguments[node.name]
152
- else
153
- argument_defn = nil
154
- end
155
- elsif stack.directive_definitions.last
156
- argument_defn = stack.directive_definitions.last.arguments[node.name]
157
- elsif stack.field_definitions.last
158
- argument_defn = stack.field_definitions.last.arguments[node.name]
159
- else
160
- argument_defn = nil
161
- end
162
- stack.argument_definitions.push(argument_defn)
163
- stack.path.push(node.name)
164
- end
165
-
166
- def pop(stack, node)
167
- stack.argument_definitions.pop
168
- stack.path.pop
169
- end
170
- end
171
-
172
- module FragmentSpreadStrategy
173
- module_function
174
- def push(stack, node)
175
- stack.path.push("... #{node.name}")
176
- end
177
-
178
- def pop(stack, node)
179
- stack.path.pop
180
- end
181
- end
182
-
183
- PUSH_STRATEGIES = {
184
- GraphQL::Language::Nodes::FragmentDefinition => FragmentDefinitionStrategy,
185
- GraphQL::Language::Nodes::InlineFragment => InlineFragmentStrategy,
186
- GraphQL::Language::Nodes::FragmentSpread => FragmentSpreadStrategy,
187
- GraphQL::Language::Nodes::Argument => ArgumentStrategy,
188
- GraphQL::Language::Nodes::Field => FieldStrategy,
189
- GraphQL::Language::Nodes::Directive => DirectiveStrategy,
190
- GraphQL::Language::Nodes::OperationDefinition => OperationDefinitionStrategy,
191
- }
192
-
193
- class EnterWithStrategy
194
- def initialize(stack, strategy)
195
- @stack = stack
196
- @strategy = strategy
197
- end
198
-
199
- def call(node, parent)
200
- @strategy.push(@stack, node)
201
- end
202
- end
203
-
204
- class LeaveWithStrategy
205
- def initialize(stack, strategy)
206
- @stack = stack
207
- @strategy = strategy
208
- end
209
-
210
- def call(node, parent)
211
- @strategy.pop(@stack, node)
212
- end
213
- end
214
- end
215
- end
216
- end