graphql 2.6.14 → 2.6.15

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 (122) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/templates/graphql_controller.erb +7 -1
  3. data/lib/graphql/analysis/max_query_complexity.rb +2 -1
  4. data/lib/graphql/analysis/max_query_depth.rb +2 -1
  5. data/lib/graphql/analysis/query_complexity.rb +2 -1
  6. data/lib/graphql/analysis/query_depth.rb +1 -1
  7. data/lib/graphql/analysis/visitor.rb +14 -2
  8. data/lib/graphql/analysis.rb +4 -5
  9. data/lib/graphql/analysis_error.rb +1 -1
  10. data/lib/graphql/coercion_error.rb +1 -1
  11. data/lib/graphql/current.rb +5 -1
  12. data/lib/graphql/dashboard.rb +1 -1
  13. data/lib/graphql/date_encoding_error.rb +3 -1
  14. data/lib/graphql/duration_encoding_error.rb +3 -1
  15. data/lib/graphql/execution/directive_checks.rb +2 -1
  16. data/lib/graphql/execution/errors.rb +18 -7
  17. data/lib/graphql/execution/field_resolve_step.rb +3 -3
  18. data/lib/graphql/execution/input_values.rb +160 -120
  19. data/lib/graphql/execution/interpreter/runtime.rb +9 -5
  20. data/lib/graphql/execution/lookahead.rb +19 -8
  21. data/lib/graphql/execution/next.rb +1 -0
  22. data/lib/graphql/execution/runner.rb +19 -12
  23. data/lib/graphql/execution/selections_step.rb +1 -1
  24. data/lib/graphql/execution/variable_values.rb +248 -0
  25. data/lib/graphql/float_decoding_error.rb +3 -1
  26. data/lib/graphql/integer_decoding_error.rb +3 -1
  27. data/lib/graphql/introspection/base_object.rb +1 -1
  28. data/lib/graphql/introspection/directive_location_enum.rb +1 -1
  29. data/lib/graphql/introspection/directive_type.rb +3 -1
  30. data/lib/graphql/introspection/dynamic_fields.rb +3 -1
  31. data/lib/graphql/introspection/enum_value_type.rb +3 -1
  32. data/lib/graphql/introspection/field_type.rb +5 -1
  33. data/lib/graphql/introspection/type_kind_enum.rb +1 -1
  34. data/lib/graphql/introspection.rb +2 -1
  35. data/lib/graphql/language/comment.rb +2 -1
  36. data/lib/graphql/language/generation.rb +2 -1
  37. data/lib/graphql/language/lexer.rb +29 -21
  38. data/lib/graphql/language/parser.rb +10 -7
  39. data/lib/graphql/language.rb +1 -1
  40. data/lib/graphql/name_validator.rb +2 -1
  41. data/lib/graphql/pagination.rb +1 -1
  42. data/lib/graphql/query/fingerprint.rb +2 -1
  43. data/lib/graphql/query/partial.rb +4 -0
  44. data/lib/graphql/query.rb +8 -12
  45. data/lib/graphql/railtie.rb +1 -1
  46. data/lib/graphql/relay.rb +1 -1
  47. data/lib/graphql/rubocop.rb +1 -1
  48. data/lib/graphql/runtime_error.rb +1 -1
  49. data/lib/graphql/runtime_type_error.rb +1 -1
  50. data/lib/graphql/schema/always_visible.rb +3 -1
  51. data/lib/graphql/schema/base_64_encoder.rb +3 -1
  52. data/lib/graphql/schema/built_in_types.rb +2 -2
  53. data/lib/graphql/schema/directive/deprecated.rb +1 -1
  54. data/lib/graphql/schema/directive/include.rb +2 -1
  55. data/lib/graphql/schema/directive/skip.rb +2 -1
  56. data/lib/graphql/schema/directive/specified_by.rb +1 -1
  57. data/lib/graphql/schema/field/scope_extension.rb +2 -1
  58. data/lib/graphql/schema/field.rb +3 -0
  59. data/lib/graphql/schema/find_inherited_value.rb +5 -1
  60. data/lib/graphql/schema/member/graphql_type_names.rb +1 -1
  61. data/lib/graphql/schema/member/has_directives.rb +20 -22
  62. data/lib/graphql/schema/member/has_path.rb +2 -1
  63. data/lib/graphql/schema/member/has_unresolved_type_error.rb +2 -1
  64. data/lib/graphql/schema/member.rb +3 -2
  65. data/lib/graphql/schema/mutation.rb +6 -1
  66. data/lib/graphql/schema/object.rb +1 -1
  67. data/lib/graphql/schema/resolver.rb +2 -2
  68. data/lib/graphql/schema/type_expression.rb +3 -1
  69. data/lib/graphql/schema/validator/all_validator.rb +6 -3
  70. data/lib/graphql/static_validation/all_rules.rb +1 -1
  71. data/lib/graphql/static_validation/base_visitor.rb +125 -53
  72. data/lib/graphql/static_validation/definition_dependencies.rb +14 -2
  73. data/lib/graphql/static_validation/interpreter_visitor.rb +1 -1
  74. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +4 -1
  75. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
  76. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +8 -4
  77. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -1
  78. data/lib/graphql/static_validation/rules/fragments_are_named.rb +2 -1
  79. data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +4 -1
  80. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +6 -3
  81. data/lib/graphql/static_validation/rules/fragments_are_used.rb +2 -1
  82. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +3 -1
  83. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +3 -2
  84. data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +4 -1
  85. data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +4 -1
  86. data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +4 -1
  87. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +9 -2
  88. data/lib/graphql/static_validation/rules/query_root_exists.rb +3 -2
  89. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +4 -1
  90. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +10 -4
  91. data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +8 -6
  92. data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +4 -1
  93. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +5 -4
  94. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +2 -1
  95. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +2 -1
  96. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -1
  97. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  98. data/lib/graphql/static_validation/validation_context.rb +49 -14
  99. data/lib/graphql/static_validation/validation_timeout_error.rb +4 -1
  100. data/lib/graphql/static_validation.rb +1 -2
  101. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +14 -13
  102. data/lib/graphql/testing.rb +1 -1
  103. data/lib/graphql/tracing/legacy_trace.rb +1 -1
  104. data/lib/graphql/tracing/null_trace.rb +1 -1
  105. data/lib/graphql/types/big_int.rb +4 -1
  106. data/lib/graphql/types/boolean.rb +3 -1
  107. data/lib/graphql/types/id.rb +3 -1
  108. data/lib/graphql/types/iso_8601_date.rb +1 -0
  109. data/lib/graphql/types/iso_8601_date_time.rb +6 -2
  110. data/lib/graphql/types/iso_8601_duration.rb +3 -0
  111. data/lib/graphql/types/relay/base_connection.rb +1 -1
  112. data/lib/graphql/types/relay/base_edge.rb +1 -1
  113. data/lib/graphql/types/relay/node.rb +1 -1
  114. data/lib/graphql/types/relay/page_info.rb +1 -1
  115. data/lib/graphql/types/relay/page_info_behaviors.rb +4 -1
  116. data/lib/graphql/types/relay.rb +1 -1
  117. data/lib/graphql/types/string.rb +1 -0
  118. data/lib/graphql/types.rb +1 -1
  119. data/lib/graphql/version.rb +2 -2
  120. metadata +3 -4
  121. data/lib/graphql/query/variables.rb +0 -99
  122. data/lib/graphql/static_validation/literal_validator.rb +0 -157
@@ -6,6 +6,7 @@ module GraphQL
6
6
  # @requires_ancestor: GraphQL::StaticValidation::BaseVisitor
7
7
  # @requires_ancestor: GraphQL::StaticValidation::RequiredInputObjectAttributesArePresent
8
8
  module OneOfInputObjectsAreValid
9
+ #: (GraphQL::Language::Nodes::InputObject node, GraphQL::Language::Nodes::AbstractNode parent) -> void
9
10
  def on_input_object(node, parent)
10
11
  return super unless parent.is_a?(GraphQL::Language::Nodes::Argument)
11
12
 
@@ -18,6 +19,7 @@ module GraphQL
18
19
 
19
20
  private
20
21
 
22
+ #: (GraphQL::Language::Nodes::InputObject ast_node, GraphQL::StaticValidation::ValidationContext context, singleton(GraphQL::Schema::InputObject) parent_type) -> void
21
23
  def validate_one_of_input_object(ast_node, context, parent_type)
22
24
  present_fields = ast_node.arguments.map(&:name)
23
25
  input_object_type = parent_type.to_type_signature
@@ -35,7 +37,9 @@ module GraphQL
35
37
  end
36
38
 
37
39
  field = present_fields.first
38
- value = ast_node.arguments.first.value
40
+ # `present_fields.count == 1` was checked above:
41
+ argument = ast_node.arguments.first #: as !nil
42
+ value = argument.value
39
43
 
40
44
  if value.is_a?(GraphQL::Language::Nodes::NullValue)
41
45
  add_error(
@@ -51,7 +55,10 @@ module GraphQL
51
55
 
52
56
  if value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
53
57
  variable_name = value.name
54
- variable_type = @declared_variables[variable_name].type
58
+ variable_definition = @declared_variables && @declared_variables[variable_name]
59
+ # Undeclared variables are reported by VariablesAreUsedAndDefined
60
+ return if variable_definition.nil?
61
+ variable_type = variable_definition.type
55
62
 
56
63
  unless variable_type.is_a?(GraphQL::Language::Nodes::NonNullType)
57
64
  add_error(
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module StaticValidation
5
5
  #--
6
6
  # @requires_ancestor: GraphQL::StaticValidation::BaseVisitor
7
7
  module QueryRootExists
8
+ #: (GraphQL::Language::Nodes::OperationDefinition node, GraphQL::Language::Nodes::AbstractNode? _parent) -> void
8
9
  def on_operation_definition(node, _parent)
9
- if (node.operation_type == 'query' || node.operation_type.nil?) && context.query.types.query_root.nil?
10
+ if (node.operation_type == 'query' || node.operation_type.nil?) && context.types.query_root.nil?
10
11
  add_error(GraphQL::StaticValidation::QueryRootExistsError.new(
11
12
  'Schema is not configured for queries',
12
13
  nodes: node
@@ -1,14 +1,16 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module StaticValidation
5
5
  class QueryRootExistsError < StaticValidation::Error
6
6
 
7
+ #: (String message, ?path: Array[String | Integer]?, ?nodes: GraphQL::Language::Nodes::AbstractNode | Array[GraphQL::Language::Nodes::AbstractNode]) -> void
7
8
  def initialize(message, path: nil, nodes: [])
8
9
  super(message, path: path, nodes: nodes)
9
10
  end
10
11
 
11
12
  # A hash representation of this Message
13
+ #: -> Hash[String, untyped]
12
14
  def to_h
13
15
  extensions = {
14
16
  "code" => code,
@@ -19,6 +21,7 @@ module GraphQL
19
21
  })
20
22
  end
21
23
 
24
+ #: -> String
22
25
  def code
23
26
  "missingQueryConfiguration"
24
27
  end
@@ -1,20 +1,25 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module StaticValidation
5
5
  class RequiredInputObjectAttributesArePresentError < StaticValidation::Error
6
+ #: String
6
7
  attr_reader :argument_type
8
+ #: String
7
9
  attr_reader :argument_name
10
+ #: String
8
11
  attr_reader :input_object_type
9
12
 
13
+ #: (String message, path: Array[String | Integer]?, nodes: GraphQL::Language::Nodes::AbstractNode | Array[GraphQL::Language::Nodes::AbstractNode], argument_type: String, argument_name: String, input_object_type: String) -> void
10
14
  def initialize(message, path:, nodes:, argument_type:, argument_name:, input_object_type:)
11
15
  super(message, path: path, nodes: nodes)
12
- @argument_type = argument_type
13
- @argument_name = argument_name
14
- @input_object_type = input_object_type
16
+ @argument_type = argument_type #: String
17
+ @argument_name = argument_name #: String
18
+ @input_object_type = input_object_type #: String
15
19
  end
16
20
 
17
21
  # A hash representation of this Message
22
+ #: () -> Hash[String, untyped]
18
23
  def to_h
19
24
  extensions = {
20
25
  "code" => code,
@@ -28,6 +33,7 @@ module GraphQL
28
33
  })
29
34
  end
30
35
 
36
+ #: () -> String
31
37
  def code
32
38
  "missingRequiredInputObjectAttribute"
33
39
  end
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module StaticValidation
5
5
  #--
6
6
  # @requires_ancestor: GraphQL::StaticValidation::BaseVisitor
7
7
  module SubscriptionRootExistsAndSingleSubscriptionSelection
8
+ #: (GraphQL::Language::Nodes::OperationDefinition node, GraphQL::Language::Nodes::AbstractNode parent) -> void
8
9
  def on_operation_definition(node, parent)
9
10
  if node.operation_type == "subscription"
10
11
  if context.types.subscription_root.nil?
@@ -34,11 +35,12 @@ module GraphQL
34
35
 
35
36
  private
36
37
 
38
+ #: (GraphQL::Language::Nodes::OperationDefinition node) -> Array[GraphQL::Language::Nodes::Field]
37
39
  def subscription_root_fields(node)
38
40
  root_type = context.types.subscription_root
39
- fields = []
40
- selections = node.selections.dup
41
- visited_fragments = {}
41
+ fields = [] #: Array[GraphQL::Language::Nodes::Field]
42
+ selections = node.selections.dup #: Array[GraphQL::Language::Nodes::Field | GraphQL::Language::Nodes::FragmentSpread | GraphQL::Language::Nodes::InlineFragment | GraphQL::Language::Nodes::FragmentDefinition]
43
+ visited_fragments = {} #: Hash[String, bool]
42
44
 
43
45
  while (selection = selections.pop)
44
46
  case selection
@@ -50,8 +52,8 @@ module GraphQL
50
52
  fragment = context.fragments[selection.name]
51
53
  selections << fragment if fragment
52
54
  when GraphQL::Language::Nodes::InlineFragment, GraphQL::Language::Nodes::FragmentDefinition
53
- fragment_type = (selection_type = selection.type) ? @types.type(selection_type.name) : root_type
54
- if fragment_type && fragment_type.kind.composite? && @types.possible_types(fragment_type).include?(root_type)
55
+ fragment_type = (selection_type = selection.type) ? types.type(selection_type.name) : root_type
56
+ if fragment_type && fragment_type.kind.composite? && types.possible_types(fragment_type).include?(root_type)
55
57
  selections.concat(selection.selections)
56
58
  end
57
59
  end
@@ -1,14 +1,16 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module StaticValidation
5
5
  class SubscriptionRootExistsError < StaticValidation::Error
6
6
 
7
+ #: (String message, ?path: Array[String | Integer]?, ?nodes: GraphQL::Language::Nodes::AbstractNode | Array[GraphQL::Language::Nodes::AbstractNode]) -> void
7
8
  def initialize(message, path: nil, nodes: [])
8
9
  super(message, path: path, nodes: nodes)
9
10
  end
10
11
 
11
12
  # A hash representation of this Message
13
+ #: -> Hash[String, untyped]
12
14
  def to_h
13
15
  extensions = {
14
16
  "code" => code,
@@ -19,6 +21,7 @@ module GraphQL
19
21
  })
20
22
  end
21
23
 
24
+ #: -> String
22
25
  def code
23
26
  "missingSubscriptionConfiguration"
24
27
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module StaticValidation
5
5
  #--
@@ -20,7 +20,7 @@ module GraphQL
20
20
  :on_enum_value_definition,
21
21
  :on_input_object_type_definition,
22
22
  :on_field,
23
- ]
23
+ ] #: Array[Symbol]
24
24
 
25
25
  VALIDATE_DIRECTIVE_LOCATION_ON_NODE = <<~RUBY
26
26
  def %{method_name}(node, parent)
@@ -37,12 +37,13 @@ module GraphQL
37
37
 
38
38
  private
39
39
 
40
+ #: (GraphQL::Language::Nodes::FragmentDefinition | GraphQL::Language::Nodes::FragmentSpread | GraphQL::Language::Nodes::InlineFragment | GraphQL::Language::Nodes::OperationDefinition | GraphQL::Language::Nodes::ScalarTypeDefinition | GraphQL::Language::Nodes::ObjectTypeDefinition | GraphQL::Language::Nodes::InputValueDefinition | GraphQL::Language::Nodes::FieldDefinition | GraphQL::Language::Nodes::InterfaceTypeDefinition | GraphQL::Language::Nodes::UnionTypeDefinition | GraphQL::Language::Nodes::EnumTypeDefinition | GraphQL::Language::Nodes::EnumValueDefinition | GraphQL::Language::Nodes::InputObjectTypeDefinition | GraphQL::Language::Nodes::Field node) -> void
40
41
  def validate_directive_location(node)
41
- used_directives = {}
42
+ used_directives = {} #: Hash[String, GraphQL::Language::Nodes::Directive]
42
43
  node.directives.each do |ast_directive|
43
44
  directive_name = ast_directive.name
44
45
  if (first_node = used_directives[directive_name])
45
- @directives_are_unique_errors_by_first_node ||= {}
46
+ @directives_are_unique_errors_by_first_node ||= {} #: Hash[GraphQL::Language::Nodes::Directive, GraphQL::StaticValidation::UniqueDirectivesPerLocationError]?
46
47
  err = @directives_are_unique_errors_by_first_node[first_node] ||= begin
47
48
  error = GraphQL::StaticValidation::UniqueDirectivesPerLocationError.new(
48
49
  "The directive \"#{directive_name}\" can only be used once at this location.",
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module StaticValidation
5
5
  #--
6
6
  # @requires_ancestor: GraphQL::StaticValidation::BaseVisitor
7
7
  module VariableDefaultValuesAreCorrectlyTyped
8
+ #: (GraphQL::Language::Nodes::VariableDefinition node, GraphQL::Language::Nodes::AbstractNode? parent) -> void
8
9
  def on_variable_definition(node, parent)
9
10
  if !node.default_value.nil?
10
11
  value = node.default_value
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module StaticValidation
5
5
  #--
6
6
  # @requires_ancestor: GraphQL::StaticValidation::BaseVisitor
7
7
  module VariableNamesAreUnique
8
+ #: (GraphQL::Language::Nodes::OperationDefinition node, GraphQL::Language::Nodes::AbstractNode? parent) -> void
8
9
  def on_operation_definition(node, parent)
9
10
  var_defns = node.variables
10
11
  if !var_defns.empty?
@@ -12,7 +12,7 @@ module GraphQL
12
12
  def initialize(*)
13
13
  super
14
14
  # holds { name => ast_node } pairs
15
- @declared_variables = {}
15
+ @declared_variables = {} #: Hash[String, GraphQL::Language::Nodes::VariableDefinition]
16
16
  @operation_declared_variables = {}.compare_by_identity #: Hash[GraphQL::Language::Nodes::OperationDefinition, Hash[String, GraphQL::Language::Nodes::VariableDefinition]]
17
17
  @variable_usages_fragment_definition = nil
18
18
  @fragment_variable_usages = nil #: Hash[GraphQL::Language::Nodes::FragmentDefinition, Array[FragmentVariableUsage]]?
@@ -7,7 +7,7 @@ module GraphQL
7
7
  module VariablesAreInputTypes
8
8
  def on_variable_definition(node, parent)
9
9
  type_name = get_type_name(node.type)
10
- type = context.query.types.type(type_name)
10
+ type = context.types.type(type_name)
11
11
 
12
12
  if type.nil?
13
13
  suggestion = if @schema.did_you_mean
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module StaticValidation
5
5
  # The validation context gets passed to each validator.
@@ -12,22 +12,40 @@ module GraphQL
12
12
  class ValidationContext
13
13
  extend Forwardable
14
14
 
15
- attr_reader :query, :errors, :visitor,
16
- :on_dependency_resolve_handlers,
17
- :max_errors, :types, :schema
15
+ #: GraphQL::Query
16
+ attr_reader :query
17
+
18
+ #: Array[GraphQL::StaticValidation::Error]
19
+ attr_reader :errors
20
+
21
+ #: GraphQL::StaticValidation::BaseVisitor
22
+ attr_reader :visitor
23
+
24
+ #: Array[^(GraphQL::Language::Nodes::OperationDefinition | GraphQL::Language::Nodes::FragmentDefinition, Array[GraphQL::Language::Nodes::FragmentSpread], GraphQL::Language::Nodes::FragmentDefinition) -> void]
25
+ attr_reader :on_dependency_resolve_handlers
26
+
27
+ #: Integer | Float
28
+ attr_reader :max_errors
29
+
30
+ #: GraphQL::Schema::Visibility::Profile | GraphQL::Schema::Warden::VisibilityProfile
31
+ attr_reader :types
32
+
33
+ #: singleton(GraphQL::Schema)
34
+ attr_reader :schema
18
35
 
19
36
 
20
37
  def_delegators :@query, :document, :fragments, :operations
21
38
 
39
+ #: (GraphQL::Query query, singleton(GraphQL::StaticValidation::BaseVisitor) visitor_class, Integer? max_errors) -> void
22
40
  def initialize(query, visitor_class, max_errors)
23
- @query = query
24
- @types = query.types # TODO update migrated callers to use this accessor
25
- @schema = query.schema
26
- @literal_validator = LiteralValidator.new(context: query.context)
27
- @errors = []
28
- @max_errors = max_errors || Float::INFINITY
29
- @on_dependency_resolve_handlers = []
30
- @visitor = visitor_class.new(document, self)
41
+ @query = query #: GraphQL::Query
42
+ @types = query.types #: GraphQL::Schema::Visibility::Profile | GraphQL::Schema::Warden::VisibilityProfile
43
+ @schema = query.schema #: singleton(GraphQL::Schema)
44
+ @input_values = query.input_values #: GraphQL::Execution::InputValues
45
+ @errors = [] #: Array[GraphQL::StaticValidation::Error]
46
+ @max_errors = max_errors || Float::INFINITY #: Integer | Float
47
+ @on_dependency_resolve_handlers = [] #: Array[^(GraphQL::Language::Nodes::OperationDefinition | GraphQL::Language::Nodes::FragmentDefinition, Array[GraphQL::Language::Nodes::FragmentSpread], GraphQL::Language::Nodes::FragmentDefinition) -> void]
48
+ @visitor = visitor_class.new(document, self) #: GraphQL::StaticValidation::BaseVisitor
31
49
  end
32
50
 
33
51
  # TODO stop using def_delegators because of Array allocations
@@ -35,22 +53,39 @@ module GraphQL
35
53
  :path, :type_definition, :field_definition, :argument_definition,
36
54
  :parent_type_definition, :directive_definition, :dependencies
37
55
 
56
+ #: () { (GraphQL::Language::Nodes::OperationDefinition | GraphQL::Language::Nodes::FragmentDefinition, Array[GraphQL::Language::Nodes::FragmentSpread], GraphQL::Language::Nodes::FragmentDefinition) -> void } -> void
38
57
  def on_dependency_resolve(&handler)
39
58
  @on_dependency_resolve_handlers << handler
40
59
  end
41
60
 
61
+ INVALID_RESULT = GraphQL::Query::InputValidationResult.new(valid: false, problems: EmptyObjects::EMPTY_ARRAY).freeze #: GraphQL::Query::InputValidationResult
62
+ private_constant :INVALID_RESULT
63
+
64
+ #: (untyped ast_value, GraphQL::Schema::Member::type_definition | GraphQL::Schema::NonNull | GraphQL::Schema::List type) -> GraphQL::Query::InputValidationResult
42
65
  def validate_literal(ast_value, type)
43
- @literal_validator.validate(ast_value, type)
66
+ @input_values.value_from_ast(ast_value, type, validate: true)
67
+ GraphQL::Query::InputValidationResult::VALID
68
+ rescue Execution::InputValues::InvalidLiteralError => err
69
+ if err.explanation
70
+ Query::InputValidationResult.from_problem(err.explanation)
71
+ else
72
+ INVALID_RESULT
73
+ end
74
+ rescue CoercionError => coercion_err
75
+ Query::InputValidationResult.from_problem(coercion_err.message, message: coercion_err.message, extensions: coercion_err.extensions)
44
76
  end
45
77
 
78
+ #: () -> bool
46
79
  def too_many_errors?
47
80
  @errors.length >= @max_errors
48
81
  end
49
82
 
83
+ #: () -> Hash[String, singleton(GraphQL::Schema::Directive)]
50
84
  def schema_directives
51
- @schema_directives ||= schema.directives
85
+ @schema_directives ||= schema.directives #: Hash[String, singleton(GraphQL::Schema::Directive)]?
52
86
  end
53
87
 
88
+ #: (String name, Array[String] options) -> String?
54
89
  def did_you_mean_suggestion(name, options)
55
90
  if did_you_mean = schema.did_you_mean
56
91
  suggestions = did_you_mean.const_get(:SpellChecker).new(dictionary: options).correct(name)
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module StaticValidation
5
5
  class ValidationTimeoutError < StaticValidation::Error
6
+ #: (String message, ?path: Array[String | Integer]?, ?nodes: GraphQL::Language::Nodes::AbstractNode | Array[GraphQL::Language::Nodes::AbstractNode]) -> void
6
7
  def initialize(message, path: nil, nodes: [])
7
8
  super(message, path: path, nodes: nodes)
8
9
  end
9
10
 
10
11
  # A hash representation of this Message
12
+ #: -> Hash[String, untyped]
11
13
  def to_h
12
14
  extensions = {
13
15
  "code" => code
@@ -18,6 +20,7 @@ module GraphQL
18
20
  })
19
21
  end
20
22
 
23
+ #: -> String
21
24
  def code
22
25
  "validationTimeout"
23
26
  end
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  require "graphql/static_validation/error"
4
4
  require "graphql/static_validation/definition_dependencies"
5
5
  require "graphql/static_validation/validator"
6
6
  require "graphql/static_validation/validation_context"
7
7
  require "graphql/static_validation/validation_timeout_error"
8
- require "graphql/static_validation/literal_validator"
9
8
  require "graphql/static_validation/base_visitor"
10
9
 
11
10
  rules_glob = File.expand_path("../static_validation/rules/*.rb", __FILE__)
@@ -106,13 +106,7 @@ module GraphQL
106
106
  # A per-process map of subscriptions to deliver.
107
107
  # This is provided by Rails, so let's use it
108
108
  @subscriptions = Concurrent::Map.new
109
- @events = Concurrent::Map.new do |h, k|
110
- h.compute_if_absent(k) do
111
- Concurrent::Map.new do |h2, k2|
112
- h2.compute_if_absent(k2) { Concurrent::Array.new }
113
- end
114
- end
115
- end
109
+ @events = Concurrent::Map.new
116
110
  @action_cable = action_cable
117
111
  @action_cable_coder = action_cable_coder
118
112
  @serializer = serializer
@@ -164,7 +158,11 @@ module GraphQL
164
158
  # Setup a new listener to run all events with this topic in this process
165
159
  setup_stream(channel, event)
166
160
  # Add this event to the list of events to be updated
167
- @events[event.topic][event.fingerprint] << event
161
+ @events.compute(event.topic) do |events_by_fingerprint|
162
+ events_by_fingerprint ||= Concurrent::Map.new
163
+ events_by_fingerprint.compute_if_absent(event.fingerprint) { Concurrent::Array.new } << event
164
+ events_by_fingerprint
165
+ end
168
166
  end
169
167
  end
170
168
 
@@ -184,6 +182,8 @@ module GraphQL
184
182
  event_stream = stream_event_name(initial_event)
185
183
  channel.stream_from(event_stream, coder: @action_cable_coder) do |message|
186
184
  events_by_fingerprint = @events[topic]
185
+ next if events_by_fingerprint.nil?
186
+
187
187
  object = nil #: untyped
188
188
  events_by_fingerprint.each do |_fingerprint, events|
189
189
  if !events.empty? && events.first == initial_event
@@ -252,11 +252,12 @@ module GraphQL
252
252
  if query
253
253
  events = query.context.namespace(:subscriptions)[:events]
254
254
  events.each do |event|
255
- ev_by_fingerprint = @events[event.topic]
256
- ev_for_fingerprint = ev_by_fingerprint[event.fingerprint]
257
- ev_for_fingerprint.delete(event)
258
- if ev_for_fingerprint.empty?
259
- ev_by_fingerprint.delete(event.fingerprint)
255
+ @events.compute_if_present(event.topic) do |events_by_fingerprint|
256
+ events_by_fingerprint.compute_if_present(event.fingerprint) do |events_for_fingerprint|
257
+ events_for_fingerprint.delete(event)
258
+ events_for_fingerprint.empty? ? nil : events_for_fingerprint
259
+ end
260
+ events_by_fingerprint.empty? ? nil : events_by_fingerprint
260
261
  end
261
262
  end
262
263
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  require "graphql/testing/helpers"
4
4
  require "graphql/testing/mock_action_cable"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
 
4
4
  require "graphql/tracing/trace"
5
5
  require "graphql/tracing/call_legacy_tracers"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
 
4
4
  require "graphql/tracing/trace"
5
5
 
@@ -1,21 +1,24 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
 
4
4
  module GraphQL
5
5
  module Types
6
6
  class BigInt < GraphQL::Schema::Scalar
7
7
  description "Represents non-fractional signed whole numeric values. Since the value may exceed the size of a 32-bit integer, it's encoded as a string."
8
8
 
9
+ #: (untyped value, GraphQL::Query::Context _ctx) -> (::Numeric | false | nil)
9
10
  def self.coerce_input(value, _ctx)
10
11
  value && parse_int(value)
11
12
  rescue ArgumentError
12
13
  nil
13
14
  end
14
15
 
16
+ #: (untyped value, GraphQL::Query::Context _ctx) -> ::String
15
17
  def self.coerce_result(value, _ctx)
16
18
  value.to_i.to_s
17
19
  end
18
20
 
21
+ #: (untyped value) -> ::Numeric
19
22
  def self.parse_int(value)
20
23
  value.is_a?(Numeric) ? value : Integer(value, 10)
21
24
  end
@@ -1,14 +1,16 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module Types
5
5
  class Boolean < GraphQL::Schema::Scalar
6
6
  description "Represents `true` or `false` values."
7
7
 
8
+ #: (untyped value, GraphQL::Query::Context _ctx) -> bool?
8
9
  def self.coerce_input(value, _ctx)
9
10
  (value == true || value == false) ? value : nil
10
11
  end
11
12
 
13
+ #: (untyped value, GraphQL::Query::Context _ctx) -> bool
12
14
  def self.coerce_result(value, _ctx)
13
15
  !!value
14
16
  end
@@ -1,15 +1,17 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module Types
5
5
  class ID < GraphQL::Schema::Scalar
6
6
  graphql_name "ID"
7
7
  description "Represents a unique identifier that is Base64 obfuscated. It is often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"VXNlci0xMA==\"`) or integer (such as `4`) input value will be accepted as an ID."
8
8
  default_scalar true
9
+ #: (untyped value, GraphQL::Query::Context _ctx) -> ::String
9
10
  def self.coerce_result(value, _ctx)
10
11
  value.is_a?(::String) ? value : value.to_s
11
12
  end
12
13
 
14
+ #: (untyped value, GraphQL::Query::Context _ctx) -> ::String?
13
15
  def self.coerce_input(value, _ctx)
14
16
  case value
15
17
  when ::String
@@ -27,6 +27,7 @@ module GraphQL
27
27
  #
28
28
  # :call-seq:
29
29
  # coerce_result(Date | Time | DateTime | String value, _ctx) -> String
30
+ #: (untyped value, GraphQL::Query::Context _ctx) -> ::String
30
31
  def self.coerce_result(value, _ctx)
31
32
  Date.parse(value.to_s).iso8601
32
33
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
 
4
4
  require 'time'
5
5
 
@@ -30,6 +30,7 @@ module GraphQL
30
30
  #
31
31
  # :call-seq:
32
32
  # time_precision() -> Integer
33
+ #: -> Integer
33
34
  def self.time_precision
34
35
  @time_precision || DEFAULT_TIME_PRECISION
35
36
  end
@@ -40,8 +41,9 @@ module GraphQL
40
41
  #
41
42
  # :call-seq:
42
43
  # time_precision=(Integer value)
44
+ #: (Integer value) -> void
43
45
  def self.time_precision=(value)
44
- @time_precision = value
46
+ @time_precision = value #: Integer?
45
47
  end
46
48
 
47
49
  # **Parameters**
@@ -54,6 +56,7 @@ module GraphQL
54
56
  #
55
57
  # :call-seq:
56
58
  # coerce_result(Time | Date | DateTime | String value, _ctx) -> String
59
+ #: (untyped value, GraphQL::Query::Context _ctx) -> ::String
57
60
  def self.coerce_result(value, _ctx)
58
61
  case value
59
62
  when Date
@@ -78,6 +81,7 @@ module GraphQL
78
81
  #
79
82
  # :call-seq:
80
83
  # coerce_input(String str_value, _ctx) -> Time
84
+ #: (untyped str_value, GraphQL::Query::Context _ctx) -> ::Time?
81
85
  def self.coerce_input(str_value, _ctx)
82
86
  Time.iso8601(str_value)
83
87
  rescue ArgumentError, TypeError
@@ -23,6 +23,7 @@ module GraphQL
23
23
  #
24
24
  # :call-seq:
25
25
  # seconds_precision() -> Integer | nil
26
+ #: -> Integer?
26
27
  def self.seconds_precision
27
28
  # ActiveSupport::Duration precision defaults to whatever input was given
28
29
  @seconds_precision
@@ -34,6 +35,7 @@ module GraphQL
34
35
  #
35
36
  # :call-seq:
36
37
  # seconds_precision=(Integer | nil value)
38
+ #: (Integer? value) -> Integer?
37
39
  def self.seconds_precision=(value)
38
40
  @seconds_precision = value
39
41
  end
@@ -52,6 +54,7 @@ module GraphQL
52
54
  #
53
55
  # :call-seq:
54
56
  # coerce_result(ActiveSupport::Duration | String value, _ctx) -> String | GraphQL::Error
57
+ #: (untyped value, GraphQL::Query::Context _ctx) -> ::String
55
58
  def self.coerce_result(value, _ctx)
56
59
  unless defined?(ActiveSupport::Duration)
57
60
  raise GraphQL::Error, "ActiveSupport >= 5.0 must be loaded to use the built-in ISO8601Duration type."
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
 
4
4
  module GraphQL
5
5
  module Types
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module Types
5
5
  module Relay
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
 
4
4
  module GraphQL
5
5
  module Types
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
  module GraphQL
4
4
  module Types
5
5
  module Relay