rubocop-graphql 0.19.0 → 1.5.4

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +86 -41
  3. data/lib/rubocop/cop/graphql/argument_description.rb +1 -0
  4. data/lib/rubocop/cop/graphql/argument_name.rb +1 -0
  5. data/lib/rubocop/cop/graphql/field_definitions.rb +21 -5
  6. data/lib/rubocop/cop/graphql/field_description.rb +1 -0
  7. data/lib/rubocop/cop/graphql/field_hash_key.rb +3 -2
  8. data/lib/rubocop/cop/graphql/field_method.rb +8 -2
  9. data/lib/rubocop/cop/graphql/field_name.rb +1 -0
  10. data/lib/rubocop/cop/graphql/field_uniqueness.rb +8 -1
  11. data/lib/rubocop/cop/graphql/graphql_name.rb +70 -0
  12. data/lib/rubocop/cop/graphql/legacy_dsl.rb +1 -0
  13. data/lib/rubocop/cop/graphql/max_complexity_schema.rb +31 -0
  14. data/lib/rubocop/cop/graphql/max_depth_schema.rb +31 -0
  15. data/lib/rubocop/cop/graphql/multiple_field_definitions.rb +2 -0
  16. data/lib/rubocop/cop/graphql/not_authorized_node_type.rb +134 -0
  17. data/lib/rubocop/cop/graphql/ordered_arguments.rb +15 -21
  18. data/lib/rubocop/cop/graphql/ordered_fields.rb +20 -15
  19. data/lib/rubocop/cop/graphql/prepare_method.rb +95 -0
  20. data/lib/rubocop/cop/graphql/resolver_method_length.rb +4 -7
  21. data/lib/rubocop/cop/graphql/unnecessary_argument_camelize.rb +11 -4
  22. data/lib/rubocop/cop/graphql/unnecessary_field_alias.rb +33 -9
  23. data/lib/rubocop/cop/graphql/unnecessary_field_camelize.rb +1 -0
  24. data/lib/rubocop/cop/graphql/unused_argument.rb +4 -5
  25. data/lib/rubocop/cop/graphql_cops.rb +5 -0
  26. data/lib/rubocop/graphql/argument/block.rb +1 -1
  27. data/lib/rubocop/graphql/compare_order.rb +51 -0
  28. data/lib/rubocop/graphql/ext/snake_case.rb +1 -1
  29. data/lib/rubocop/graphql/field.rb +5 -2
  30. data/lib/rubocop/graphql/heredoc.rb +12 -5
  31. data/lib/rubocop/graphql/schema_member.rb +1 -1
  32. data/lib/rubocop/graphql/sorbet.rb +2 -10
  33. data/lib/rubocop/graphql/version.rb +1 -1
  34. data/lib/rubocop-graphql.rb +1 -0
  35. metadata +11 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80b3609f1de18b1e5db7198fdf29f7deed28cfe0e505c9485203dd38172ff4f9
4
- data.tar.gz: 0d894dad1bc37192b76372d235d10fab4181e171574f471091e9bad0033212d2
3
+ metadata.gz: e0d8efee42cd1c4f7443f6d83ffcf7f0aeb030de07573486bbf12bc9f758e0a2
4
+ data.tar.gz: 4bc42c5823b8dceca37a2ca48b086478c7fa360817f864ce4ee2c420e103fba0
5
5
  SHA512:
6
- metadata.gz: 3c2b2d1bcbae2e53e28567c0f13397f77427cc0b9d87a96171cd27fec5d33649568366a623c6ea7c6960f452709d02081c04e3dae1368b465da4fad304ae9ce5
7
- data.tar.gz: b6b5588432b38eaa545bff20b2f52d966859ba1fac6fcad5004f22405fd4d1dab56c04238124f99f3ff1df860b385773e539981221b94d0e8c4c27266d4a7c9e
6
+ metadata.gz: addcc849a825b94134f1d19743a10a7c6784d984831b41f3b9e0292c2aca6a2ab1d055bd97fae7fed9a918d4edf865f8c4d81684f43d0b9b981dab782669b476
7
+ data.tar.gz: c7958b6e456137e98f4116954b6982d417eab63202ce4da778fd154a70620159e44ce69da7cac078a25d983a917ebfbc02f9acfcf11681f90399be911307df2b
data/config/default.yml CHANGED
@@ -8,123 +8,168 @@ GraphQL:
8
8
 
9
9
  GraphQL/ArgumentDescription:
10
10
  Enabled: true
11
- VersionAdded: '0.80'
11
+ VersionAdded: '0.2.0'
12
12
  Description: 'Ensures all arguments have a description'
13
13
 
14
14
  GraphQL/ArgumentName:
15
15
  Enabled: true
16
- VersionAdded: '0.80'
16
+ VersionAdded: '0.2.0'
17
17
  Description: 'This cop checks whether argument names are snake_case'
18
18
 
19
19
  GraphQL/ArgumentUniqueness:
20
20
  Enabled: true
21
- VersionAdded: '0.80'
21
+ VersionAdded: '0.11.0'
22
22
  Description: 'This cop enforces arguments to be defined once per block'
23
23
 
24
- GraphQL/ResolverMethodLength:
24
+ GraphQL/ExtractInputType:
25
25
  Enabled: true
26
- VersionAdded: '0.80'
27
- Description: 'Checks resolver methods are not too long'
28
- Max: 10
29
- CountComments: false
30
- ExcludedMethods: []
26
+ VersionAdded: '0.2.0'
27
+ Description: 'Suggests using input type instead of many arguments'
28
+ MaxArguments: 2
29
+ Include:
30
+ - '**/graphql/mutations/**/*.rb'
31
+
32
+ GraphQL/ExtractType:
33
+ Enabled: true
34
+ VersionAdded: '0.2.0'
35
+ Description: 'Suggests extracting fields with common prefixes to the separate type'
36
+ MaxFields: 2
37
+ Prefixes:
38
+ - is
39
+ - has
40
+ - with
41
+ - avg
42
+ - min
43
+ - max
31
44
 
32
45
  GraphQL/FieldDefinitions:
33
46
  Enabled: true
34
- VersionAdded: '0.80'
47
+ VersionAdded: '0.1.0'
35
48
  Description: 'Checks consistency of field definitions'
36
49
  EnforcedStyle: group_definitions
37
50
  SupportedStyles:
38
51
  - group_definitions
39
52
  - define_resolver_after_definition
40
53
 
41
- GraphQL/MultipleFieldDefinitions:
42
- Enabled: true
43
- Description: 'Ensures that fields with multiple definitions are grouped together'
44
-
45
54
  GraphQL/FieldDescription:
46
55
  Enabled: true
47
- VersionAdded: '0.80'
56
+ VersionAdded: '0.1.0'
48
57
  Description: 'Ensures all fields have a description'
49
58
 
50
59
  GraphQL/FieldHashKey:
51
60
  Enabled: true
52
- VersionAdded: '0.80'
61
+ VersionAdded: '0.4.0'
53
62
  Description: 'Checks :hash_key option is used for appropriate fields'
54
63
 
55
64
  GraphQL/FieldMethod:
56
65
  Enabled: true
57
- VersionAdded: '0.80'
66
+ VersionAdded: '0.2.0'
58
67
  Description: 'Checks :method option is used for appropriate fields'
59
68
 
60
69
  GraphQL/FieldName:
61
70
  Enabled: true
62
- VersionAdded: '0.80'
71
+ VersionAdded: '0.2.0'
63
72
  Description: 'This cop checks whether field names are snake_case'
64
73
  SafeAutoCorrect: false
65
74
 
66
75
  GraphQL/FieldUniqueness:
67
76
  Enabled: true
68
- VersionAdded: '0.80'
77
+ VersionAdded: '0.11.0'
69
78
  Description: 'This cop enforces fields to be defined once'
70
79
 
71
- GraphQL/ExtractInputType:
80
+ GraphQL/GraphqlName:
72
81
  Enabled: true
73
- VersionAdded: '0.80'
74
- Description: 'Suggests using input type instead of many arguments'
75
- MaxArguments: 2
82
+ VersionAdded: '1.0.0'
83
+ Description: 'This cop check proper configuration of graphql_name'
76
84
  Include:
77
- - '**/graphql/mutations/**/*.rb'
78
-
79
- GraphQL/ExtractType:
80
- Enabled: true
81
- VersionAdded: '0.80'
82
- Description: 'Suggests extracting fields with common prefixes to the separate type'
83
- MaxFields: 2
84
- Prefixes:
85
- - is
86
- - has
87
- - with
88
- - avg
89
- - min
90
- - max
85
+ - "**/graphql/types/**/*"
86
+ - "**/graphql/mutations/**/*"
87
+ EnforcedStyle: only_override
88
+ SupportedStyles:
89
+ - required
90
+ - only_override
91
91
 
92
92
  GraphQL/LegacyDsl:
93
93
  Enabled: true
94
- VersionAdded: '0.80'
94
+ VersionAdded: '0.9.0'
95
95
  Description: 'Checks that types are defined with class-based API'
96
96
 
97
+ GraphQL/MaxComplexitySchema:
98
+ Enabled: true
99
+ VersionAdded: '1.0.0'
100
+ Description: 'Enforces max_complexity configuration in schema'
101
+ Include:
102
+ - '**/graphql/**/*_schema.rb'
103
+
104
+ GraphQL/MaxDepthSchema:
105
+ Enabled: true
106
+ VersionAdded: '1.0.0'
107
+ Description: 'Enforces max_depth configuration in schema'
108
+ Include:
109
+ - '**/graphql/**/*_schema.rb'
110
+
111
+ GraphQL/MultipleFieldDefinitions:
112
+ Enabled: true
113
+ VersionAdded: '0.15.0'
114
+ Description: 'Ensures that fields with multiple definitions are grouped together'
115
+
116
+ GraphQL/NotAuthorizedNodeType:
117
+ Enabled: true
118
+ VersionAdded: '1.0.0'
119
+ Description: 'Detects types that implement Node interface and not have `.authorized?` check'
120
+ Include:
121
+ - '**/graphql/types/**/*'
122
+ SafeBaseClasses: []
123
+
124
+ GraphQL/ResolverMethodLength:
125
+ Enabled: true
126
+ VersionAdded: '0.1.0'
127
+ Description: 'Checks resolver methods are not too long'
128
+ Max: 10
129
+ CountComments: false
130
+ ExcludedMethods: []
131
+ CountAsOne: []
132
+
97
133
  GraphQL/ObjectDescription:
98
134
  Enabled: true
99
- VersionAdded: '0.80'
135
+ VersionAdded: '0.3.0'
100
136
  Description: 'Ensures all types have a description'
101
137
  Exclude:
138
+ - "spec/**/*"
139
+ - "test/**/*"
102
140
  - '**/*_schema.rb'
103
141
  - '**/base_*.rb'
104
142
  - '**/graphql/query_context.rb'
105
143
 
106
144
  GraphQL/OrderedArguments:
107
145
  Enabled: true
108
- VersionAdded: '0.80'
146
+ VersionAdded: '0.7.0'
109
147
  Description: 'Arguments should be alphabetically sorted within groups'
148
+ Order: null
110
149
 
111
150
  GraphQL/OrderedFields:
112
151
  Enabled: true
113
- VersionAdded: '0.80'
152
+ VersionAdded: '0.5.0'
114
153
  Description: 'Fields should be alphabetically sorted within groups'
154
+ Groups: true
155
+ Order: null
115
156
 
116
157
  GraphQL/UnusedArgument:
117
158
  Enabled: true
159
+ VersionAdded: '0.12.0'
118
160
  Description: 'Arguments should either be listed explicitly or **rest should be in the resolve signature'
119
161
 
120
162
  GraphQL/UnnecessaryFieldAlias:
121
163
  Enabled: true
164
+ VersionAdded: '0.18.0'
122
165
  Description: 'Field aliases should be different than their field names'
123
166
 
124
167
  GraphQL/UnnecessaryArgumentCamelize:
125
168
  Enabled: true
169
+ VersionAdded: '0.18.0'
126
170
  Description: "Camelize isn't necessary if the argument name doesn't contain underscores"
127
171
 
128
172
  GraphQL/UnnecessaryFieldCamelize:
129
173
  Enabled: true
174
+ VersionAdded: '0.18.0'
130
175
  Description: "Camelize isn't necessary if the field name doesn't contain underscores"
@@ -22,6 +22,7 @@ module RuboCop
22
22
  include RuboCop::GraphQL::NodePattern
23
23
 
24
24
  MSG = "Missing argument description"
25
+ RESTRICT_ON_SEND = %i[argument].freeze
25
26
 
26
27
  def on_send(node)
27
28
  return unless argument?(node)
@@ -20,6 +20,7 @@ module RuboCop
20
20
  #
21
21
  class ArgumentName < Base
22
22
  include RuboCop::GraphQL::NodePattern
23
+ RESTRICT_ON_SEND = %i[argument].freeze
23
24
 
24
25
  using RuboCop::GraphQL::Ext::SnakeCase
25
26
 
@@ -47,11 +47,14 @@ module RuboCop
47
47
  class FieldDefinitions < Base # rubocop:disable Metrics/ClassLength
48
48
  extend AutoCorrector
49
49
  include ConfigurableEnforcedStyle
50
+ include CommentsHelp
50
51
  include RuboCop::GraphQL::NodePattern
51
52
  include RuboCop::Cop::RangeHelp
52
53
  include RuboCop::GraphQL::Sorbet
53
54
  include RuboCop::GraphQL::Heredoc
54
55
 
56
+ RESTRICT_ON_SEND = %i[field].freeze
57
+
55
58
  # @!method field_kwargs(node)
56
59
  def_node_matcher :field_kwargs, <<~PATTERN
57
60
  (send nil? :field
@@ -80,6 +83,16 @@ module RuboCop
80
83
  end
81
84
  end
82
85
 
86
+ def on_module(node)
87
+ return if style != :group_definitions
88
+
89
+ schema_member = RuboCop::GraphQL::SchemaMember.new(node)
90
+
91
+ if (body = schema_member.body)
92
+ check_grouped_field_declarations(body)
93
+ end
94
+ end
95
+
83
96
  private
84
97
 
85
98
  GROUP_DEFS_MSG = "Group all field definitions together."
@@ -100,7 +113,6 @@ module RuboCop
100
113
 
101
114
  def group_field_declarations(corrector, node)
102
115
  field = RuboCop::GraphQL::Field.new(node)
103
-
104
116
  first_field = field.schema_member.body.find do |node|
105
117
  field_definition?(node) || field_definition_with_body?(node)
106
118
  end
@@ -201,17 +213,19 @@ module RuboCop
201
213
  end
202
214
 
203
215
  def insert_new_resolver(corrector, field_definition, resolver_definition)
216
+ resolver_definition_range = source_range_with_comment(resolver_definition)
204
217
  source_to_insert =
205
218
  "\n#{signature_to_insert(resolver_definition)}\n" \
206
- "#{indent(resolver_definition)}#{resolver_definition.source}\n"
219
+ "#{indent(resolver_definition)}#{resolver_definition_range.source.strip}\n"
207
220
 
208
221
  field_definition_range = range_including_heredoc(field_definition)
209
222
  corrector.insert_after(field_definition_range, source_to_insert)
210
223
  end
211
224
 
212
225
  def remove_old_resolver(corrector, resolver_definition)
226
+ resolver_definition_range = source_range_with_comment(resolver_definition)
213
227
  range_to_remove = range_with_surrounding_space(
214
- range: resolver_definition.loc.expression, side: :left
228
+ range: resolver_definition_range, side: :left
215
229
  )
216
230
  corrector.remove(range_to_remove)
217
231
 
@@ -219,8 +233,9 @@ module RuboCop
219
233
 
220
234
  return unless resolver_signature
221
235
 
236
+ resolver_signature_range = source_range_with_comment(resolver_signature)
222
237
  range_to_remove = range_with_surrounding_space(
223
- range: resolver_signature.loc.expression, side: :left
238
+ range: resolver_signature_range, side: :left
224
239
  )
225
240
  corrector.remove(range_to_remove)
226
241
  end
@@ -230,7 +245,8 @@ module RuboCop
230
245
 
231
246
  return unless signature
232
247
 
233
- "\n#{indent(signature)}#{signature.source}"
248
+ range = source_range_with_comment(signature)
249
+ "\n#{indent(signature)}#{range.source.strip}"
234
250
  end
235
251
 
236
252
  def indent(node)
@@ -22,6 +22,7 @@ module RuboCop
22
22
  include RuboCop::GraphQL::NodePattern
23
23
 
24
24
  MSG = "Missing field description"
25
+ RESTRICT_ON_SEND = %i[field].freeze
25
26
 
26
27
  def on_send(node)
27
28
  return unless field_definition?(node)
@@ -41,6 +41,7 @@ module RuboCop
41
41
  PATTERN
42
42
 
43
43
  MSG = "Use hash_key: %<hash_key>p"
44
+ RESTRICT_ON_SEND = %i[field].freeze
44
45
 
45
46
  def on_send(node)
46
47
  return unless field_definition?(node)
@@ -74,11 +75,11 @@ module RuboCop
74
75
  suggested_hash_key_name = hash_key_to_use(method_definition)
75
76
 
76
77
  corrector.insert_after(
77
- node.loc.expression, ", hash_key: #{suggested_hash_key_name.inspect}"
78
+ node, ", hash_key: #{suggested_hash_key_name.inspect}"
78
79
  )
79
80
 
80
81
  range = range_with_surrounding_space(
81
- range: method_definition.loc.expression, side: :left
82
+ range: method_definition.source_range, side: :left
82
83
  )
83
84
 
84
85
  corrector.remove(range)
@@ -40,6 +40,7 @@ module RuboCop
40
40
  PATTERN
41
41
 
42
42
  MSG = "Use method: :%<method_name>s"
43
+ RESTRICT_ON_SEND = %i[field].freeze
43
44
 
44
45
  def on_send(node)
45
46
  return unless field_definition?(node)
@@ -51,6 +52,7 @@ module RuboCop
51
52
 
52
53
  return if suggested_method_name.nil?
53
54
  return if RuboCop::GraphQL::Field::CONFLICT_FIELD_NAMES.include?(suggested_method_name)
55
+ return if method_kwarg_set?(field)
54
56
 
55
57
  add_offense(node, message: message(suggested_method_name)) do |corrector|
56
58
  autocorrect(corrector, node)
@@ -68,10 +70,10 @@ module RuboCop
68
70
  method_definition = suggest_method_name_for(field)
69
71
  suggested_method_name = method_to_use(method_definition)
70
72
 
71
- corrector.insert_after(node.loc.expression, ", method: :#{suggested_method_name}")
73
+ corrector.insert_after(node, ", method: :#{suggested_method_name}")
72
74
 
73
75
  range = range_with_surrounding_space(
74
- range: method_definition.loc.expression, side: :left
76
+ range: method_definition.source_range, side: :left
75
77
  )
76
78
  corrector.remove(range)
77
79
  end
@@ -80,6 +82,10 @@ module RuboCop
80
82
  method_name = field.resolver_method_name
81
83
  field.schema_member.find_method_definition(method_name)
82
84
  end
85
+
86
+ def method_kwarg_set?(field)
87
+ field.kwargs.method != nil
88
+ end
83
89
  end
84
90
  end
85
91
  end
@@ -29,6 +29,7 @@ module RuboCop
29
29
  using RuboCop::GraphQL::Ext::SnakeCase
30
30
 
31
31
  MSG = "Use snake_case for field names"
32
+ RESTRICT_ON_SEND = %i[field].freeze
32
33
 
33
34
  def on_send(node)
34
35
  return unless field_definition?(node)
@@ -63,9 +63,16 @@ module RuboCop
63
63
  end
64
64
 
65
65
  def field_name(node)
66
- node.first_argument.value.to_s
66
+ field = RuboCop::GraphQL::Field.new(node)
67
+
68
+ "#{field.name}#{':non-camelized' if false_value?(field.kwargs.camelize)}"
67
69
  end
68
70
 
71
+ # @!method false_value?(node)
72
+ def_node_matcher :false_value?, <<~PATTERN
73
+ (pair ... false)
74
+ PATTERN
75
+
69
76
  # @!method field_declarations(node)
70
77
  def_node_search :field_declarations, <<~PATTERN
71
78
  {
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module GraphQL
6
+ # Checks consistency of graphql_name usage
7
+ #
8
+ # EnforcedStyle supports two modes:
9
+ #
10
+ # `only_override` : types and mutations should have graphql_name configured only if it's
11
+ # different from the default name
12
+ #
13
+ # `required` : all types and mutations should have graphql_name configured
14
+ #
15
+ # @example EnforcedStyle: only_override (default)
16
+ # # good
17
+ #
18
+ # class UserType < BaseType
19
+ # graphql_name 'Viewer'
20
+ # end
21
+ #
22
+ # # bad
23
+ #
24
+ # class UserType < BaseType
25
+ # graphql_name 'User'
26
+ # end
27
+ #
28
+ # @example EnforcedStyle: required
29
+ # # good
30
+ #
31
+ # class UserType < BaseType
32
+ # graphql_name 'User'
33
+ # end
34
+ #
35
+ # # bad
36
+ #
37
+ # class UserType < BaseType
38
+ # end
39
+ #
40
+ class GraphqlName < Base
41
+ include ConfigurableEnforcedStyle
42
+
43
+ # @!method graphql_name(node)
44
+ def_node_matcher :graphql_name, <<~PATTERN
45
+ `(send nil? :graphql_name (str $_))
46
+ PATTERN
47
+
48
+ # @!method class_name(node)
49
+ def_node_matcher :class_name, <<~PATTERN
50
+ (class (const _ $_) ...)
51
+ PATTERN
52
+
53
+ MISSING_NAME = "graphql_name should be configured."
54
+ UNNEEDED_OVERRIDE = "graphql_name should be specified only for overrides."
55
+
56
+ def on_class(node)
57
+ specified_name = graphql_name(node)
58
+
59
+ case style
60
+ when :required
61
+ add_offense(node, message: MISSING_NAME) if specified_name.nil?
62
+ when :only_override
63
+ default_graphql_name = class_name(node).to_s.sub(/Type\Z/, "")
64
+ add_offense(node, message: UNNEEDED_OVERRIDE) if specified_name == default_graphql_name
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -32,6 +32,7 @@ module RuboCop
32
32
 
33
33
  MSG = "Avoid using legacy based type-based definitions. " \
34
34
  "Use class-based definitions instead."
35
+ RESTRICT_ON_SEND = %i[define].freeze
35
36
 
36
37
  def on_send(node)
37
38
  return unless node.parent.block_type?
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module GraphQL
6
+ # Detects missing max_complexity configuration in schema files
7
+ #
8
+ # @example
9
+ # # good
10
+ #
11
+ # class AppSchema < BaseSchema
12
+ # max_complexity 42
13
+ # end
14
+ #
15
+ class MaxComplexitySchema < Base
16
+ # @!method max_complexity(node)
17
+ def_node_matcher :max_complexity, <<~PATTERN
18
+ `(send nil? :max_complexity ...)
19
+ PATTERN
20
+
21
+ MSG = "max_complexity should be configured for schema."
22
+
23
+ def on_class(node)
24
+ return if ::RuboCop::GraphQL::Class.new(node).nested? || max_complexity(node)
25
+
26
+ add_offense(node)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module GraphQL
6
+ # Detects missing max_depth configuration in schema files
7
+ #
8
+ # @example
9
+ # # good
10
+ #
11
+ # class AppSchema < BaseSchema
12
+ # max_depth 42
13
+ # end
14
+ #
15
+ class MaxDepthSchema < Base
16
+ # @!method max_depth(node)
17
+ def_node_matcher :max_depth, <<~PATTERN
18
+ `(send nil? :max_depth ...)
19
+ PATTERN
20
+
21
+ MSG = "max_depth should be configured for schema."
22
+
23
+ def on_class(node)
24
+ return if ::RuboCop::GraphQL::Class.new(node).nested? || max_depth(node)
25
+
26
+ add_offense(node)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -32,6 +32,8 @@ module RuboCop
32
32
  include RuboCop::Cop::RangeHelp
33
33
  include RuboCop::GraphQL::Heredoc
34
34
 
35
+ RESTRICT_ON_SEND = %i[field].freeze
36
+
35
37
  def on_send(node)
36
38
  return unless field?(node)
37
39