graphql 2.4.1 → 2.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 12a25d94ae9348527390bad889be7c918390c0a1b133735612ac5a80ca0c6633
4
- data.tar.gz: de4bb61a31dc643d359157dff498410f70a5a7bd18d6c254463a2a5294706949
3
+ metadata.gz: bbf9779d0fbc1da481a481d987489b980818c5ea6afb352f4e65f0654ea14163
4
+ data.tar.gz: 91528aabb657b8602c7f3143b6a9dc3a770a336f6a31af0f89fce1c27e5e00a0
5
5
  SHA512:
6
- metadata.gz: f85c5a5e4ab0083862c990fe6cd3f0ed99d36a414721d4c3d0a7a3e5c59042cdc5611a6b74d10d0e18525d9e51a32dc6aa1a2349c789b04dae75a835f4bb322a
7
- data.tar.gz: e0304dded75753771417672c704054a1daec13ab428ed92f97dbdcee2771f21874bfb6aedf9bd0054806ed97b4483b98376f03526b129d96628735c1933f0d35
6
+ metadata.gz: c73cedf9cd1fc6ab4d91f026dfe627cb1490d5888d1252f591b944359e1f537a479c5d7f7ceed691ddd79883ae1ba027dfb952e969d14617e6a19becee792aa6
7
+ data.tar.gz: 4d429bb74350c9fbbaa0e33498ccb193acfa6691f62342b38923965e69bc23bb377e6ade8a56b8f5d5c785ea24a2f6e04a47a8384000a45140d320e7461c6832
@@ -404,7 +404,7 @@ module GraphQL
404
404
  end
405
405
  end
406
406
 
407
- entry_point_types.compact! # TODO why is this necessary?!
407
+ entry_point_types.compact! # Root types might be nil
408
408
  entry_point_types.flatten! # handle multiple defns
409
409
  entry_point_types.each { |t| add_type(t, true) }
410
410
 
@@ -21,11 +21,27 @@ module GraphQL
21
21
  if migration_errors
22
22
  schema.visibility_profile_class = Migration
23
23
  end
24
+ @preload = preload
24
25
  @profiles = profiles
25
26
  @cached_profiles = {}
26
27
  @dynamic = dynamic
27
28
  @migration_errors = migration_errors
28
29
  if preload
30
+ # Traverse the schema now (and in the *_configured hooks below)
31
+ # To make sure things are loaded during boot
32
+ @preloaded_types = Set.new
33
+ types_to_visit = [
34
+ @schema.query,
35
+ @schema.mutation,
36
+ @schema.subscription,
37
+ *@schema.introspection_system.types.values,
38
+ *@schema.introspection_system.entry_points.map { |ep| ep.type.unwrap },
39
+ *@schema.orphan_types,
40
+ ]
41
+ # Root types may have been nil:
42
+ types_to_visit.compact!
43
+ ensure_all_loaded(types_to_visit)
44
+
29
45
  profiles.each do |profile_name, example_ctx|
30
46
  example_ctx[:visibility_profile] = profile_name
31
47
  prof = profile_for(example_ctx, profile_name)
@@ -34,6 +50,45 @@ module GraphQL
34
50
  end
35
51
  end
36
52
 
53
+ # @api private
54
+ def query_configured(query_type)
55
+ if @preload
56
+ ensure_all_loaded([query_type])
57
+ end
58
+ end
59
+
60
+ # @api private
61
+ def mutation_configured(mutation_type)
62
+ if @preload
63
+ ensure_all_loaded([mutation_type])
64
+ end
65
+ end
66
+
67
+ # @api private
68
+ def subscription_configured(subscription_type)
69
+ if @preload
70
+ ensure_all_loaded([subscription_type])
71
+ end
72
+ end
73
+
74
+ # @api private
75
+ def orphan_types_configured(orphan_types)
76
+ if @preload
77
+ ensure_all_loaded(orphan_types)
78
+ end
79
+ end
80
+
81
+ # @api private
82
+ def introspection_system_configured(introspection_system)
83
+ if @preload
84
+ introspection_types = [
85
+ *@schema.introspection_system.types.values,
86
+ *@schema.introspection_system.entry_points.map { |ep| ep.type.unwrap },
87
+ ]
88
+ ensure_all_loaded(introspection_types)
89
+ end
90
+ end
91
+
37
92
  # Make another Visibility for `schema` based on this one
38
93
  # @return [Visibility]
39
94
  # @api private
@@ -70,6 +125,19 @@ module GraphQL
70
125
  @schema.visibility_profile_class.new(context: context, schema: @schema)
71
126
  end
72
127
  end
128
+
129
+ private
130
+
131
+ def ensure_all_loaded(types_to_visit)
132
+ while (type = types_to_visit.shift)
133
+ if type.kind.fields? && @preloaded_types.add?(type)
134
+ type.all_field_definitions.each do |field_defn|
135
+ field_defn.ensure_loaded
136
+ types_to_visit << field_defn.type.unwrap
137
+ end
138
+ end
139
+ end
140
+ end
73
141
  end
74
142
  end
75
143
  end
@@ -445,7 +445,12 @@ module GraphQL
445
445
  dup_defn = new_query_object || yield
446
446
  raise GraphQL::Error, "Second definition of `query(...)` (#{dup_defn.inspect}) is invalid, already configured with #{@query_object.inspect}"
447
447
  elsif use_visibility_profile?
448
- @query_object = block_given? ? lazy_load_block : new_query_object
448
+ if block_given?
449
+ @query_object = lazy_load_block
450
+ else
451
+ @query_object = new_query_object
452
+ self.visibility.query_configured(@query_object)
453
+ end
449
454
  else
450
455
  @query_object = new_query_object || lazy_load_block.call
451
456
  add_type_and_traverse(@query_object, root: true)
@@ -453,6 +458,8 @@ module GraphQL
453
458
  nil
454
459
  elsif @query_object.is_a?(Proc)
455
460
  @query_object = @query_object.call
461
+ self.visibility&.query_configured(@query_object)
462
+ @query_object
456
463
  else
457
464
  @query_object || find_inherited_value(:query)
458
465
  end
@@ -472,7 +479,12 @@ module GraphQL
472
479
  dup_defn = new_mutation_object || yield
473
480
  raise GraphQL::Error, "Second definition of `mutation(...)` (#{dup_defn.inspect}) is invalid, already configured with #{@mutation_object.inspect}"
474
481
  elsif use_visibility_profile?
475
- @mutation_object = block_given? ? lazy_load_block : new_mutation_object
482
+ if block_given?
483
+ @mutation_object = lazy_load_block
484
+ else
485
+ @mutation_object = new_mutation_object
486
+ self.visibility.mutation_configured(@mutation_object)
487
+ end
476
488
  else
477
489
  @mutation_object = new_mutation_object || lazy_load_block.call
478
490
  add_type_and_traverse(@mutation_object, root: true)
@@ -480,6 +492,8 @@ module GraphQL
480
492
  nil
481
493
  elsif @mutation_object.is_a?(Proc)
482
494
  @mutation_object = @mutation_object.call
495
+ self.visibility&.mutation_configured(@query_object)
496
+ @mutation_object
483
497
  else
484
498
  @mutation_object || find_inherited_value(:mutation)
485
499
  end
@@ -499,7 +513,12 @@ module GraphQL
499
513
  dup_defn = new_subscription_object || yield
500
514
  raise GraphQL::Error, "Second definition of `subscription(...)` (#{dup_defn.inspect}) is invalid, already configured with #{@subscription_object.inspect}"
501
515
  elsif use_visibility_profile?
502
- @subscription_object = block_given? ? lazy_load_block : new_subscription_object
516
+ if block_given?
517
+ @subscription_object = lazy_load_block
518
+ else
519
+ @subscription_object = new_subscription_object
520
+ self.visibility.subscription_configured(@subscription_object)
521
+ end
503
522
  add_subscription_extension_if_necessary
504
523
  else
505
524
  @subscription_object = new_subscription_object || lazy_load_block.call
@@ -510,6 +529,7 @@ module GraphQL
510
529
  elsif @subscription_object.is_a?(Proc)
511
530
  @subscription_object = @subscription_object.call
512
531
  add_subscription_extension_if_necessary
532
+ self.visibility.subscription_configured(@subscription_object)
513
533
  @subscription_object
514
534
  else
515
535
  @subscription_object || find_inherited_value(:subscription)
@@ -695,20 +715,27 @@ module GraphQL
695
715
  type.fields(context)
696
716
  end
697
717
 
718
+ # Pass a custom introspection module here to use it for this schema.
719
+ # @param new_introspection_namespace [Module] If given, use this module for custom introspection on the schema
720
+ # @return [Module, nil] The configured namespace, if there is one
698
721
  def introspection(new_introspection_namespace = nil)
699
722
  if new_introspection_namespace
700
723
  @introspection = new_introspection_namespace
701
724
  # reset this cached value:
702
725
  @introspection_system = nil
726
+ introspection_system
727
+ @introspection
703
728
  else
704
729
  @introspection || find_inherited_value(:introspection)
705
730
  end
706
731
  end
707
732
 
733
+ # @return [Schema::IntrospectionSystem] Based on {introspection}
708
734
  def introspection_system
709
735
  if !@introspection_system
710
736
  @introspection_system = Schema::IntrospectionSystem.new(self)
711
737
  @introspection_system.resolve_late_bindings
738
+ self.visibility&.introspection_system_configured(@introspection_system)
712
739
  end
713
740
  @introspection_system
714
741
  end
@@ -952,6 +979,13 @@ module GraphQL
952
979
  end
953
980
  end
954
981
 
982
+ # Tell the schema about these types so that they can be registered as implementations of interfaces in the schema.
983
+ #
984
+ # This method must be used when an object type is connected to the schema as an interface implementor but
985
+ # not as a return type of a field. In that case, if the object type isn't registered here, GraphQL-Ruby won't be able to find it.
986
+ #
987
+ # @param new_orphan_types [Array<Class<GraphQL::Schema::Object>>] Object types to register as implementations of interfaces in the schema.
988
+ # @return [Array<Class<GraphQL::Schema::Object>>] All previously-registered orphan types for this schema
955
989
  def orphan_types(*new_orphan_types)
956
990
  if new_orphan_types.any?
957
991
  new_orphan_types = new_orphan_types.flatten
@@ -968,6 +1002,7 @@ module GraphQL
968
1002
  end
969
1003
  add_type_and_traverse(new_orphan_types, root: false) unless use_visibility_profile?
970
1004
  own_orphan_types.concat(new_orphan_types.flatten)
1005
+ self.visibility&.orphan_types_configured(new_orphan_types)
971
1006
  end
972
1007
 
973
1008
  inherited_ot = find_inherited_value(:orphan_types, nil)
@@ -14,7 +14,9 @@ module GraphQL
14
14
  node_name: parent_type.graphql_name
15
15
  ))
16
16
  else
17
- message = "Field '#{node.name}' doesn't exist on type '#{parent_type.graphql_name}'#{context.did_you_mean_suggestion(node.name, context.types.fields(parent_type).map(&:graphql_name))}"
17
+ possible_fields = possible_fields(context, parent_type)
18
+ suggestion = context.did_you_mean_suggestion(node.name, possible_fields)
19
+ message = "Field '#{node.name}' doesn't exist on type '#{parent_type.graphql_name}'#{suggestion}"
18
20
  add_error(GraphQL::StaticValidation::FieldsAreDefinedOnTypeError.new(
19
21
  message,
20
22
  nodes: node,
@@ -26,6 +28,13 @@ module GraphQL
26
28
  super
27
29
  end
28
30
  end
31
+
32
+ private
33
+
34
+ def possible_fields(context, parent_type)
35
+ return EmptyObjects::EMPTY_ARRAY if parent_type.kind.leaf?
36
+ context.types.fields(parent_type).map(&:graphql_name)
37
+ end
29
38
  end
30
39
  end
31
40
  end
@@ -25,7 +25,7 @@ module GraphQL
25
25
  def validate_field_selections(ast_node, resolved_type)
26
26
  msg = if resolved_type.nil?
27
27
  nil
28
- elsif resolved_type.kind.scalar? && ast_node.selections.any?
28
+ elsif ast_node.selections.any? && resolved_type.kind.leaf?
29
29
  selection_strs = ast_node.selections.map do |n|
30
30
  case n
31
31
  when GraphQL::Language::Nodes::InlineFragment
@@ -38,7 +38,7 @@ module GraphQL
38
38
  raise "Invariant: unexpected selection node: #{n}"
39
39
  end
40
40
  end
41
- "Selections can't be made on scalars (%{node_name} returns #{resolved_type.graphql_name} but has selections [#{selection_strs.join(", ")}])"
41
+ "Selections can't be made on #{resolved_type.kind.name.sub("_", " ").downcase}s (%{node_name} returns #{resolved_type.graphql_name} but has selections [#{selection_strs.join(", ")}])"
42
42
  elsif resolved_type.kind.fields? && ast_node.selections.empty?
43
43
  "Field must have selections (%{node_name} returns #{resolved_type.graphql_name} but has no selections. Did you mean '#{ast_node.name} { ... }'?)"
44
44
  else
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "2.4.1"
3
+ VERSION = "2.4.2"
4
4
  end
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.4.1
4
+ version: 2.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-04 00:00:00.000000000 Z
11
+ date: 2024-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64