graphql 1.10.0.pre3 → 1.10.0.pre4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/templates/schema.erb +7 -0
  3. data/lib/graphql/argument.rb +3 -35
  4. data/lib/graphql/define/assign_enum_value.rb +1 -1
  5. data/lib/graphql/define/assign_object_field.rb +3 -3
  6. data/lib/graphql/define/defined_object_proxy.rb +8 -2
  7. data/lib/graphql/define/instance_definable.rb +10 -106
  8. data/lib/graphql/directive.rb +4 -0
  9. data/lib/graphql/enum_type.rb +1 -71
  10. data/lib/graphql/execution/execute.rb +1 -1
  11. data/lib/graphql/execution/interpreter/runtime.rb +48 -8
  12. data/lib/graphql/execution/multiplex.rb +3 -3
  13. data/lib/graphql/field.rb +1 -117
  14. data/lib/graphql/function.rb +1 -30
  15. data/lib/graphql/input_object_type.rb +1 -23
  16. data/lib/graphql/interface_type.rb +1 -22
  17. data/lib/graphql/language/document_from_schema_definition.rb +9 -3
  18. data/lib/graphql/language/nodes.rb +2 -2
  19. data/lib/graphql/object_type.rb +1 -21
  20. data/lib/graphql/query.rb +0 -1
  21. data/lib/graphql/query/context.rb +2 -5
  22. data/lib/graphql/relay/connection_type.rb +2 -1
  23. data/lib/graphql/relay/edge_type.rb +1 -0
  24. data/lib/graphql/relay/mutation.rb +1 -86
  25. data/lib/graphql/relay/node.rb +2 -2
  26. data/lib/graphql/scalar_type.rb +1 -58
  27. data/lib/graphql/schema.rb +60 -9
  28. data/lib/graphql/schema/build_from_definition.rb +6 -1
  29. data/lib/graphql/schema/directive.rb +7 -1
  30. data/lib/graphql/schema/enum_value.rb +1 -0
  31. data/lib/graphql/schema/introspection_system.rb +4 -1
  32. data/lib/graphql/schema/list.rb +17 -2
  33. data/lib/graphql/schema/loader.rb +9 -3
  34. data/lib/graphql/schema/mutation.rb +1 -1
  35. data/lib/graphql/schema/object.rb +0 -4
  36. data/lib/graphql/schema/relay_classic_mutation.rb +1 -1
  37. data/lib/graphql/schema/resolver.rb +1 -1
  38. data/lib/graphql/schema/subscription.rb +5 -5
  39. data/lib/graphql/schema/type_membership.rb +1 -1
  40. data/lib/graphql/schema/union.rb +1 -1
  41. data/lib/graphql/subscriptions.rb +2 -2
  42. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +1 -1
  43. data/lib/graphql/tracing.rb +7 -3
  44. data/lib/graphql/tracing/active_support_notifications_tracing.rb +4 -0
  45. data/lib/graphql/tracing/appsignal_tracing.rb +8 -0
  46. data/lib/graphql/tracing/data_dog_tracing.rb +8 -0
  47. data/lib/graphql/tracing/new_relic_tracing.rb +8 -0
  48. data/lib/graphql/tracing/platform_tracing.rb +25 -4
  49. data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
  50. data/lib/graphql/tracing/scout_tracing.rb +8 -0
  51. data/lib/graphql/tracing/skylight_tracing.rb +8 -0
  52. data/lib/graphql/union_type.rb +12 -27
  53. data/lib/graphql/version.rb +1 -1
  54. metadata +8 -8
@@ -44,9 +44,9 @@ module GraphQL
44
44
  end
45
45
 
46
46
  class << self
47
- def run_all(schema, query_options, *args)
48
- queries = query_options.map { |opts| GraphQL::Query.new(schema, nil, opts) }
49
- run_queries(schema, queries, *args)
47
+ def run_all(schema, query_options, **kwargs)
48
+ queries = query_options.map { |opts| GraphQL::Query.new(schema, nil, **opts) }
49
+ run_queries(schema, queries, **kwargs)
50
50
  end
51
51
 
52
52
  # @param schema [GraphQL::Schema]
@@ -2,123 +2,7 @@
2
2
  require "graphql/field/resolve"
3
3
 
4
4
  module GraphQL
5
- # {Field}s belong to {ObjectType}s and {InterfaceType}s.
6
- #
7
- # They're usually created with the `field` helper. If you create it by hand, make sure {#name} is a String.
8
- #
9
- # A field must have a return type, but if you want to defer the return type calculation until later,
10
- # you can pass a proc for the return type. That proc will be called when the schema is defined.
11
- #
12
- # @example Lazy type resolution
13
- # # If the field's type isn't defined yet, you can pass a proc
14
- # field :city, -> { TypeForModelName.find("City") }
15
- #
16
- # For complex field definition, you can pass a block to the `field` helper, eg `field :name do ... end`.
17
- # This block is equivalent to calling `GraphQL::Field.define { ... }`.
18
- #
19
- # @example Defining a field with a block
20
- # field :city, CityType do
21
- # # field definition continues inside the block
22
- # end
23
- #
24
- # ## Resolve
25
- #
26
- # Fields have `resolve` functions to determine their values at query-time.
27
- # The default implementation is to call a method on the object based on the field name.
28
- #
29
- # @example Create a field which calls a method with the same name.
30
- # GraphQL::ObjectType.define do
31
- # field :name, types.String, "The name of this thing "
32
- # end
33
- #
34
- # You can specify a custom proc with the `resolve` helper.
35
- #
36
- # There are some shortcuts for common `resolve` implementations:
37
- # - Provide `property:` to call a method with a different name than the field name
38
- # - Provide `hash_key:` to resolve the field by doing a key lookup, eg `obj[:my_hash_key]`
39
- #
40
- # @example Create a field that calls a different method on the object
41
- # GraphQL::ObjectType.define do
42
- # # use the `property` keyword:
43
- # field :firstName, types.String, property: :first_name
44
- # end
45
- #
46
- # @example Create a field looks up with `[hash_key]`
47
- # GraphQL::ObjectType.define do
48
- # # use the `hash_key` keyword:
49
- # field :firstName, types.String, hash_key: :first_name
50
- # end
51
- #
52
- # ## Arguments
53
- #
54
- # Fields can take inputs; they're called arguments. You can define them with the `argument` helper.
55
- #
56
- # @example Create a field with an argument
57
- # field :students, types[StudentType] do
58
- # argument :grade, types.Int
59
- # resolve ->(obj, args, ctx) {
60
- # Student.where(grade: args[:grade])
61
- # }
62
- # end
63
- #
64
- # They can have default values which will be provided to `resolve` if the query doesn't include a value.
65
- #
66
- # @example Argument with a default value
67
- # field :events, types[EventType] do
68
- # # by default, don't include past events
69
- # argument :includePast, types.Boolean, default_value: false
70
- # resolve ->(obj, args, ctx) {
71
- # args[:includePast] # => false if no value was provided in the query
72
- # # ...
73
- # }
74
- # end
75
- #
76
- # Only certain types maybe used for inputs:
77
- #
78
- # - Scalars
79
- # - Enums
80
- # - Input Objects
81
- # - Lists of those types
82
- #
83
- # Input types may also be non-null -- in that case, the query will fail
84
- # if the input is not present.
85
- #
86
- # ## Complexity
87
- #
88
- # Fields can have _complexity_ values which describe the computation cost of resolving the field.
89
- # You can provide the complexity as a constant with `complexity:` or as a proc, with the `complexity` helper.
90
- #
91
- # @example Custom complexity values
92
- # # Complexity can be a number or a proc.
93
- #
94
- # # Complexity can be defined with a keyword:
95
- # field :expensive_calculation, !types.Int, complexity: 10
96
- #
97
- # # Or inside the block:
98
- # field :expensive_calculation_2, !types.Int do
99
- # complexity ->(ctx, args, child_complexity) { ctx[:current_user].staff? ? 0 : 10 }
100
- # end
101
- #
102
- # @example Calculating the complexity of a list field
103
- # field :items, types[ItemType] do
104
- # argument :limit, !types.Int
105
- # # Multiply the child complexity by the possible items on the list
106
- # complexity ->(ctx, args, child_complexity) { child_complexity * args[:limit] }
107
- # end
108
- #
109
- # @example Creating a field, then assigning it to a type
110
- # name_field = GraphQL::Field.define do
111
- # name("Name")
112
- # type(!types.String)
113
- # description("The name of this thing")
114
- # resolve ->(object, arguments, context) { object.name }
115
- # end
116
- #
117
- # NamedType = GraphQL::ObjectType.define do
118
- # # The second argument may be a GraphQL::Field
119
- # field :name, name_field
120
- # end
121
- #
5
+ # @api deprecated
122
6
  class Field
123
7
  include GraphQL::Define::InstanceDefinable
124
8
  accepts_definitions :name, :description, :deprecation_reason,
@@ -1,35 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- # A reusable container for field logic, including arguments, resolve, return type, and documentation.
4
- #
5
- # Class-level values defined with the DSL will be inherited,
6
- # so {GraphQL::Function}s can extend one another.
7
- #
8
- # It's OK to override the instance methods here in order to customize behavior of instances.
9
- #
10
- # @example A reusable GraphQL::Function attached as a field
11
- # class FindRecord < GraphQL::Function
12
- # attr_reader :type
13
- #
14
- # def initialize(model:, type:)
15
- # @model = model
16
- # @type = type
17
- # end
18
- #
19
- # argument :id, GraphQL::ID_TYPE
20
- #
21
- # def call(obj, args, ctx)
22
- # @model.find(args.id)
23
- # end
24
- # end
25
- #
26
- # QueryType = GraphQL::ObjectType.define do
27
- # name "Query"
28
- # field :post, function: FindRecord.new(model: Post, type: PostType)
29
- # field :comment, function: FindRecord.new(model: Comment, type: CommentType)
30
- # end
31
- #
32
- # @see {GraphQL::Schema::Resolver} for a replacement for `GraphQL::Function`
3
+ # @api deprecated
33
4
  class Function
34
5
  # @return [Hash<String => GraphQL::Argument>] Arguments, keyed by name
35
6
  def arguments
@@ -1,28 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- # {InputObjectType}s are key-value inputs for fields.
4
- #
5
- # Input objects have _arguments_ which are identical to {GraphQL::Field} arguments.
6
- # They map names to types and support default values.
7
- # Their input types can be any input types, including {InputObjectType}s.
8
- #
9
- # @example An input type with name and number
10
- # PlayerInput = GraphQL::InputObjectType.define do
11
- # name("Player")
12
- # argument :name, !types.String
13
- # argument :number, !types.Int
14
- # end
15
- #
16
- # In a `resolve` function, you can access the values by making nested lookups on `args`.
17
- #
18
- # @example Accessing input values in a resolve function
19
- # resolve ->(obj, args, ctx) {
20
- # args[:player][:name] # => "Tony Gwynn"
21
- # args[:player][:number] # => 19
22
- # args[:player].to_h # { "name" => "Tony Gwynn", "number" => 19 }
23
- # # ...
24
- # }
25
- #
3
+ # @api deprecated
26
4
  class InputObjectType < GraphQL::BaseType
27
5
  accepts_definitions(
28
6
  :arguments, :mutation,
@@ -1,27 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- # An Interface contains a collection of types which implement some of the same fields.
4
- #
5
- # Interfaces can have fields, defined with `field`, just like an object type.
6
- #
7
- # Objects which implement this field _inherit_ field definitions from the interface.
8
- # An object type can override the inherited definition by redefining that field.
9
- #
10
- # @example An interface with three fields
11
- # DeviceInterface = GraphQL::InterfaceType.define do
12
- # name("Device")
13
- # description("Hardware devices for computing")
14
- #
15
- # field :ram, types.String
16
- # field :processor, ProcessorType
17
- # field :release_year, types.Int
18
- # end
19
- #
20
- # @example Implementing an interface with an object type
21
- # Laptoptype = GraphQL::ObjectType.define do
22
- # interfaces [DeviceInterface]
23
- # end
24
- #
3
+ # @api deprecated
25
4
  class InterfaceType < GraphQL::BaseType
26
5
  accepts_definitions :fields, :orphan_types, :resolve_type, field: GraphQL::Define::AssignObjectField
27
6
 
@@ -23,10 +23,16 @@ module GraphQL
23
23
  @include_built_in_scalars = include_built_in_scalars
24
24
  @include_built_in_directives = include_built_in_directives
25
25
 
26
+ filter = GraphQL::Filter.new(only: only, except: except)
27
+ if @schema.respond_to?(:visible?)
28
+ filter = filter.merge(only: @schema.method(:visible?))
29
+ end
30
+
31
+ schema_context = schema.context_class.new(query: nil, object: nil, schema: schema, values: context)
26
32
  @warden = GraphQL::Schema::Warden.new(
27
- GraphQL::Filter.new(only: only, except: except),
33
+ filter,
28
34
  schema: @schema,
29
- context: context,
35
+ context: schema_context,
30
36
  )
31
37
  end
32
38
 
@@ -250,7 +256,7 @@ module GraphQL
250
256
  definitions = []
251
257
  definitions << build_schema_node if include_schema_node?
252
258
  definitions += build_directive_nodes(warden.directives)
253
- definitions += build_type_definition_nodes(warden.types.values)
259
+ definitions += build_type_definition_nodes(warden.reachable_types)
254
260
  definitions
255
261
  end
256
262
 
@@ -25,7 +25,7 @@ module GraphQL
25
25
  # Initialize a node by extracting its position,
26
26
  # then calling the class's `initialize_node` method.
27
27
  # @param options [Hash] Initial attributes for this node
28
- def initialize(options={})
28
+ def initialize(options = {})
29
29
  if options.key?(:position_source)
30
30
  position_source = options.delete(:position_source)
31
31
  @line = position_source.line
@@ -34,7 +34,7 @@ module GraphQL
34
34
 
35
35
  @filename = options.delete(:filename)
36
36
 
37
- initialize_node(options)
37
+ initialize_node(**options)
38
38
  end
39
39
 
40
40
  # Value equality
@@ -1,26 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- # This type exposes fields on an object.
4
- #
5
- # @example defining a type for your IMDB clone
6
- # MovieType = GraphQL::ObjectType.define do
7
- # name "Movie"
8
- # description "A full-length film or a short film"
9
- # interfaces [ProductionInterface, DurationInterface]
10
- #
11
- # field :runtimeMinutes, !types.Int, property: :runtime_minutes
12
- # field :director, PersonType
13
- # field :cast, CastType
14
- # field :starring, types[PersonType] do
15
- # argument :limit, types.Int
16
- # resolve ->(object, args, ctx) {
17
- # stars = object.cast.stars
18
- # args[:limit] && stars = stars.limit(args[:limit])
19
- # stars
20
- # }
21
- # end
22
- # end
23
- #
3
+ # @api deprecated
24
4
  class ObjectType < GraphQL::BaseType
25
5
  accepts_definitions :interfaces, :fields, :mutation, :relay_node_type, field: GraphQL::Define::AssignObjectField
26
6
  accepts_definitions implements: ->(type, *interfaces, inherit: false) { type.implements(interfaces, inherit: inherit) }
@@ -140,7 +140,6 @@ module GraphQL
140
140
  @executed = false
141
141
 
142
142
  # TODO add a general way to define schema-level filters
143
- # TODO also add this to schema dumps
144
143
  if @schema.respond_to?(:visible?)
145
144
  merge_filters(only: @schema.method(:visible?))
146
145
  end
@@ -143,9 +143,9 @@ module GraphQL
143
143
  # Make a new context which delegates key lookup to `values`
144
144
  # @param query [GraphQL::Query] the query who owns this context
145
145
  # @param values [Hash] A hash of arbitrary values which will be accessible at query-time
146
- def initialize(query:, values: , object:)
146
+ def initialize(query:, schema: query.schema, values:, object:)
147
147
  @query = query
148
- @schema = query.schema
148
+ @schema = schema
149
149
  @provided_values = values || {}
150
150
  @object = object
151
151
  # Namespaced storage, where user-provided values are in `nil` namespace:
@@ -334,6 +334,3 @@ module GraphQL
334
334
  end
335
335
  end
336
336
  end
337
-
338
-
339
- GraphQL::Schema::Context = GraphQL::Query::Context
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
3
  module Relay
4
+ # @api deprecated
4
5
  module ConnectionType
5
6
  class << self
6
7
  # @return [Boolean] If true, connection types get a `nodes` shortcut field
@@ -12,7 +13,7 @@ module GraphQL
12
13
  self.default_nodes_field = false
13
14
  self.bidirectional_pagination = false
14
15
 
15
- # Create a connection which exposes edges of this type
16
+ # @api deprecated
16
17
  def self.create_type(wrapped_type, edge_type: nil, edge_class: GraphQL::Relay::Edge, nodes_field: ConnectionType.default_nodes_field, &block)
17
18
  custom_edge_class = edge_class
18
19
 
@@ -2,6 +2,7 @@
2
2
  module GraphQL
3
3
  module Relay
4
4
  module EdgeType
5
+ # @api deprecated
5
6
  def self.create_type(wrapped_type, name: nil, &block)
6
7
  GraphQL::ObjectType.define do
7
8
  type_name = wrapped_type.is_a?(GraphQL::BaseType) ? wrapped_type.name : wrapped_type.graphql_name
@@ -5,92 +5,7 @@ require "graphql/relay/mutation/result"
5
5
 
6
6
  module GraphQL
7
7
  module Relay
8
- # Define a Relay mutation:
9
- # - give it a name (used for derived inputs & outputs)
10
- # - declare its inputs
11
- # - declare its outputs
12
- # - declare the mutation procedure
13
- #
14
- # `resolve` should return a hash with a key for each of the `return_field`s
15
- #
16
- # Inputs may also contain a `clientMutationId`
17
- #
18
- # @example Updating the name of an item
19
- # UpdateNameMutation = GraphQL::Relay::Mutation.define do
20
- # name "UpdateName"
21
- #
22
- # input_field :name, !types.String
23
- # input_field :itemId, !types.ID
24
- #
25
- # return_field :item, ItemType
26
- #
27
- # resolve ->(inputs, ctx) {
28
- # item = Item.find_by_id(inputs[:id])
29
- # item.update(name: inputs[:name])
30
- # {item: item}
31
- # }
32
- # end
33
- #
34
- # MutationType = GraphQL::ObjectType.define do
35
- # # The mutation object exposes a field:
36
- # field :updateName, field: UpdateNameMutation.field
37
- # end
38
- #
39
- # # Then query it:
40
- # query_string = %|
41
- # mutation updateName {
42
- # updateName(input: {itemId: 1, name: "new name", clientMutationId: "1234"}) {
43
- # item { name }
44
- # clientMutationId
45
- # }|
46
- #
47
- # GraphQL::Query.new(MySchema, query_string).result
48
- # # {"data" => {
49
- # # "updateName" => {
50
- # # "item" => { "name" => "new name"},
51
- # # "clientMutationId" => "1234"
52
- # # }
53
- # # }}
54
- #
55
- # @example Using a GraphQL::Function
56
- # class UpdateAttributes < GraphQL::Function
57
- # attr_reader :model, :return_as, :arguments
58
- #
59
- # def initialize(model:, return_as:, attributes:)
60
- # @model = model
61
- # @arguments = {}
62
- # attributes.each do |name, type|
63
- # arg_name = name.to_s
64
- # @arguments[arg_name] = GraphQL::Argument.define(name: arg_name, type: type)
65
- # end
66
- # @arguments["id"] = GraphQL::Argument.define(name: "id", type: !GraphQL::ID_TYPE)
67
- # @return_as = return_as
68
- # @attributes = attributes
69
- # end
70
- #
71
- # def type
72
- # fn = self
73
- # GraphQL::ObjectType.define do
74
- # name "Update#{fn.model.name}AttributesResponse"
75
- # field :clientMutationId, types.ID
76
- # field fn.return_as.keys[0], fn.return_as.values[0]
77
- # end
78
- # end
79
- #
80
- # def call(obj, args, ctx)
81
- # record = @model.find(args[:inputs][:id])
82
- # new_values = {}
83
- # @attributes.each { |a| new_values[a] = args[a] }
84
- # record.update(new_values)
85
- # { @return_as => record }
86
- # end
87
- # end
88
- #
89
- # UpdateNameMutation = GraphQL::Relay::Mutation.define do
90
- # name "UpdateName"
91
- # function UpdateAttributes.new(model: Item, return_as: { item: ItemType }, attributes: {name: !types.String})
92
- # end
93
-
8
+ # @api deprecated
94
9
  class Mutation
95
10
  include GraphQL::Define::InstanceDefinable
96
11
  accepts_definitions(