rubocop-graphql 1.2.0 → 1.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95e3cd9f39f4d6349f89ae259d9ea98569ce58680600319f5c5e9e846b789653
4
- data.tar.gz: e1f1cf02c677f0de30913b18c60ae8dfee94e537e8dc5d70d31b291d6bb67767
3
+ metadata.gz: 5dc015328dbeffe70db24816b19cc9252244e5311ce2957ceb970a08a6812132
4
+ data.tar.gz: 5763888eb52a54c529d02e2f7f01560002c5172cace12ea440b85e64e7a0898d
5
5
  SHA512:
6
- metadata.gz: 2823101dc6985bac70575d7ef73e9d600c47491759b128f1a9af47f5ac47148cbb5d3163150bfb34a97eb7dfca71c9b2498f11c0fa9ec08ee31e56d066f35f38
7
- data.tar.gz: 6f468a9a2c4e5c630a7b8d8bee2f7575efead50bf3365980f347359a3a14174b81d8dbf5ada3c48b5cc407a005fa745b1b2d02c97a07135aac8b67e295be11e2
6
+ metadata.gz: d5e22e52e4b9e4c090dcec11933bb2fa8e22134c49963088828c9352190e0f4b834ede4e4f280402e904ad8c099db987645b689107860571172898c52e1c61b0
7
+ data.tar.gz: 284ef533642cdaf70e75dda615e77406eba375d607827f40c59bbdc47e714d5b0be724bfc710189ccc211a9f3a5cf558eb38ee161bc81c559285db88a12df0d8
data/config/default.yml CHANGED
@@ -119,6 +119,7 @@ GraphQL/NotAuthorizedNodeType:
119
119
  Description: 'Detects types that implement Node interface and not have `.authorized?` check'
120
120
  Include:
121
121
  - '**/graphql/types/**/*'
122
+ SafeBaseClasses: []
122
123
 
123
124
  GraphQL/ResolverMethodLength:
124
125
  Enabled: true
@@ -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
 
@@ -52,6 +52,8 @@ module RuboCop
52
52
  include RuboCop::GraphQL::Sorbet
53
53
  include RuboCop::GraphQL::Heredoc
54
54
 
55
+ RESTRICT_ON_SEND = %i[field].freeze
56
+
55
57
  # @!method field_kwargs(node)
56
58
  def_node_matcher :field_kwargs, <<~PATTERN
57
59
  (send nil? :field
@@ -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)
@@ -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)
@@ -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)
@@ -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?
@@ -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
 
@@ -7,6 +7,12 @@ module RuboCop
7
7
  # Such types can be fetched by ID and therefore should have type level check to
8
8
  # avoid accidental information exposure.
9
9
  #
10
+ # If `.authorized?` is defined in a parent class, you can add parent to the "SafeBaseClasses"
11
+ # to avoid offenses in children.
12
+ #
13
+ # This cop also checks the `can_can_action` or `pundit_role` methods that
14
+ # can be used as part of the Ruby GraphQL Pro.
15
+ #
10
16
  # @example
11
17
  # # good
12
18
  #
@@ -34,6 +40,26 @@ module RuboCop
34
40
  # end
35
41
  # end
36
42
  #
43
+ # # good
44
+ #
45
+ # class UserType < BaseType
46
+ # implements GraphQL::Types::Relay::Node
47
+ #
48
+ # pundit_role :staff
49
+ #
50
+ # field :uuid, ID, null: false
51
+ # end
52
+ #
53
+ # # good
54
+ #
55
+ # class UserType < BaseType
56
+ # implements GraphQL::Types::Relay::Node
57
+ #
58
+ # can_can_action :staff
59
+ #
60
+ # field :uuid, ID, null: false
61
+ # end
62
+ #
37
63
  # # bad
38
64
  #
39
65
  # class UserType < BaseType
@@ -54,13 +80,53 @@ module RuboCop
54
80
  (const nil? :GraphQL) :Types) :Relay) :Node))
55
81
  PATTERN
56
82
 
83
+ # @!method has_can_can_action?(node)
84
+ def_node_matcher :has_can_can_action?, <<~PATTERN
85
+ `(send nil? :can_can_action {nil_type? sym_type?})
86
+ PATTERN
87
+
88
+ # @!method has_pundit_role?(node)
89
+ def_node_matcher :has_pundit_role?, <<~PATTERN
90
+ `(send nil? :pundit_role {nil_type? sym_type?})
91
+ PATTERN
92
+
57
93
  # @!method has_authorized_method?(node)
58
94
  def_node_matcher :has_authorized_method?, <<~PATTERN
59
95
  {`(:defs (:self) :authorized? ...) | `(:sclass (:self) `(:def :authorized? ...))}
60
96
  PATTERN
61
97
 
98
+ def on_module(node)
99
+ @parent_modules ||= []
100
+ @parent_modules << node.child_nodes[0].const_name
101
+ end
102
+
62
103
  def on_class(node)
63
- add_offense(node) if implements_node_type?(node) && !has_authorized_method?(node)
104
+ @parent_modules ||= []
105
+ return if possible_parent_classes(node).any? { |klass| ignored_class?(klass) }
106
+
107
+ @parent_modules << node.child_nodes[0].const_name
108
+
109
+ add_offense(node) if implements_node_type?(node) && !implements_authorization?(node)
110
+ end
111
+
112
+ private
113
+
114
+ def implements_authorization?(node)
115
+ has_authorized_method?(node) || has_can_can_action?(node) || has_pundit_role?(node)
116
+ end
117
+
118
+ def possible_parent_classes(node)
119
+ klass = node.child_nodes[1].const_name
120
+
121
+ return [] if klass.nil?
122
+ return [klass] if node.child_nodes[1].absolute?
123
+
124
+ parent_module = "#{@parent_modules.join('::')}::"
125
+ [klass, parent_module + klass]
126
+ end
127
+
128
+ def ignored_class?(klass)
129
+ cop_config["SafeBaseClasses"].include?(klass)
64
130
  end
65
131
  end
66
132
  end
@@ -10,27 +10,33 @@ module RuboCop
10
10
  #
11
11
  # class UserType < BaseType
12
12
  # field :name, String, "Name of the user", null: true do
13
- # argument :filter, String, required: false, camelize: false
13
+ # argument :filter, String, required: false
14
14
  # end
15
15
  # end
16
16
  #
17
17
  # # good
18
18
  #
19
19
  # class UserType < BaseType
20
- # argument :filter, String, required: false, camelize: false
20
+ # argument :filter, String, required: false
21
+ # end
22
+ #
23
+ # # good
24
+ #
25
+ # class UserType < BaseType
26
+ # argument :email_filter, String, required: false, camelize: true
21
27
  # end
22
28
  #
23
29
  # # bad
24
30
  #
25
31
  # class UserType < BaseType
26
- # argument :filter, String, required: false
32
+ # argument :filter, String, required: false, camelize: false
27
33
  # end
28
34
  #
29
35
  # # bad
30
36
  #
31
37
  # class UserType < BaseType
32
38
  # field :name, String, "Name of the user", null: true do
33
- # argument :filter, String, required: false
39
+ # argument :filter, String, required: false, camelize: false
34
40
  # end
35
41
  # end
36
42
  #
@@ -38,6 +44,7 @@ module RuboCop
38
44
  include RuboCop::GraphQL::NodePattern
39
45
 
40
46
  MSG = "Unnecessary argument camelize"
47
+ RESTRICT_ON_SEND = %i[argument].freeze
41
48
 
42
49
  def on_send(node)
43
50
  return unless argument?(node)
@@ -25,6 +25,7 @@ module RuboCop
25
25
  include RuboCop::GraphQL::NodePattern
26
26
 
27
27
  MSG = "Unnecessary :%<kwarg>s configured"
28
+ RESTRICT_ON_SEND = %i[field].freeze
28
29
 
29
30
  def on_send(node)
30
31
  return unless field_definition?(node)
@@ -22,6 +22,7 @@ module RuboCop
22
22
  include RuboCop::GraphQL::NodePattern
23
23
 
24
24
  MSG = "Unnecessary field camelize"
25
+ RESTRICT_ON_SEND = %i[field].freeze
25
26
 
26
27
  def on_send(node)
27
28
  return unless field_definition?(node)
@@ -1,5 +1,5 @@
1
1
  module RuboCop
2
2
  module GraphQL
3
- VERSION = "1.2.0".freeze
3
+ VERSION = "1.4.0".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Tsepelev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-06 00:00:00.000000000 Z
11
+ date: 2023-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -58,7 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '0.87'
61
+ version: '0.90'
62
62
  - - "<"
63
63
  - !ruby/object:Gem::Version
64
64
  version: '2'
@@ -68,7 +68,7 @@ dependencies:
68
68
  requirements:
69
69
  - - ">="
70
70
  - !ruby/object:Gem::Version
71
- version: '0.87'
71
+ version: '0.90'
72
72
  - - "<"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '2'