rubocop-graphql 1.1.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4bcabdbafaf927896c569183254a11c60352414d91978553dcc12449cc45b46c
4
- data.tar.gz: b9edc6b4444b21ecde01fceffbb027489aa59241886ba1f6e09f1488ae73a0f2
3
+ metadata.gz: 9cdf5152e0106f86e952fbf5a24a38011914f34b0167a19ef0cf53dd810e4d68
4
+ data.tar.gz: 9ed0ac94bdc4f323543e1085a612dfb3d02f5e60ee55892da6894b202718865e
5
5
  SHA512:
6
- metadata.gz: 02fbc1b2402f0661737a188a5aa107376210ba30ca52d1461da8e5ba7312ef2c548d3485ea2630194422e4379368f4efd595b0ac2c6affdc4432939344c7f956
7
- data.tar.gz: 6472b601c9ba130fe97eac98d556a4f9113884e95290c8c751d321c123d1ff54ac31396d7fc53885001c55a62a3e66941547a4dd5f761af5e72a7a1b46f74a2c
6
+ metadata.gz: 992563e33d74e91766b4917a541ef9361795156f93eb33a95f0944e4968f87a5845681adff07178a30cd11b10c6b2e10ea002e2688b2a501cc6b9e25bb1bc103
7
+ data.tar.gz: 2cf037f19ca63a512ea00a06601cf49dcc46ed5bb59deec1ede2e45dcd74acfd875b7febf7f703b36354fa4059dd222ca5f37fb59a11572c7cc8d4ffb97389a9
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
@@ -141,12 +142,14 @@ GraphQL/OrderedArguments:
141
142
  Enabled: true
142
143
  VersionAdded: '0.7.0'
143
144
  Description: 'Arguments should be alphabetically sorted within groups'
145
+ Order: null
144
146
 
145
147
  GraphQL/OrderedFields:
146
148
  Enabled: true
147
149
  VersionAdded: '0.5.0'
148
150
  Description: 'Fields should be alphabetically sorted within groups'
149
151
  Groups: true
152
+ Order: null
150
153
 
151
154
  GraphQL/UnusedArgument:
152
155
  Enabled: true
@@ -74,7 +74,7 @@ module RuboCop
74
74
  suggested_hash_key_name = hash_key_to_use(method_definition)
75
75
 
76
76
  corrector.insert_after(
77
- node.source_range, ", hash_key: #{suggested_hash_key_name.inspect}"
77
+ node, ", hash_key: #{suggested_hash_key_name.inspect}"
78
78
  )
79
79
 
80
80
  range = range_with_surrounding_space(
@@ -51,6 +51,7 @@ module RuboCop
51
51
 
52
52
  return if suggested_method_name.nil?
53
53
  return if RuboCop::GraphQL::Field::CONFLICT_FIELD_NAMES.include?(suggested_method_name)
54
+ return if method_kwarg_set?(field)
54
55
 
55
56
  add_offense(node, message: message(suggested_method_name)) do |corrector|
56
57
  autocorrect(corrector, node)
@@ -68,7 +69,7 @@ module RuboCop
68
69
  method_definition = suggest_method_name_for(field)
69
70
  suggested_method_name = method_to_use(method_definition)
70
71
 
71
- corrector.insert_after(node.source_range, ", method: :#{suggested_method_name}")
72
+ corrector.insert_after(node, ", method: :#{suggested_method_name}")
72
73
 
73
74
  range = range_with_surrounding_space(
74
75
  range: method_definition.source_range, side: :left
@@ -80,6 +81,10 @@ module RuboCop
80
81
  method_name = field.resolver_method_name
81
82
  field.schema_member.find_method_definition(method_name)
82
83
  end
84
+
85
+ def method_kwarg_set?(field)
86
+ field.kwargs.method != nil
87
+ end
83
88
  end
84
89
  end
85
90
  end
@@ -7,6 +7,9 @@ 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
+ #
10
13
  # @example
11
14
  # # good
12
15
  #
@@ -45,6 +48,11 @@ module RuboCop
45
48
  class NotAuthorizedNodeType < Base
46
49
  MSG = ".authorized? should be defined for types implementing Node interface."
47
50
 
51
+ # @!method class_name(node)
52
+ def_node_matcher :class_name, <<~PATTERN
53
+ (const nil? $_)
54
+ PATTERN
55
+
48
56
  # @!method implements_node_type?(node)
49
57
  def_node_matcher :implements_node_type?, <<~PATTERN
50
58
  `(send nil? :implements
@@ -60,8 +68,20 @@ module RuboCop
60
68
  PATTERN
61
69
 
62
70
  def on_class(node)
71
+ return if ignored_class?(parent_class(node))
72
+
63
73
  add_offense(node) if implements_node_type?(node) && !has_authorized_method?(node)
64
74
  end
75
+
76
+ private
77
+
78
+ def parent_class(node)
79
+ node.child_nodes[1]
80
+ end
81
+
82
+ def ignored_class?(node)
83
+ cop_config["SafeBaseClasses"].include?(String(class_name(node)))
84
+ end
65
85
  end
66
86
  end
67
87
  end
@@ -52,6 +52,7 @@ module RuboCop
52
52
  extend AutoCorrector
53
53
 
54
54
  include RuboCop::GraphQL::SwapRange
55
+ include RuboCop::GraphQL::CompareOrder
55
56
 
56
57
  MSG = "Arguments should be sorted in an alphabetical order within their section. " \
57
58
  "Field `%<current>s` should appear before `%<previous>s`."
@@ -71,7 +72,7 @@ module RuboCop
71
72
 
72
73
  argument_declarations.each_cons(2) do |previous, current|
73
74
  next unless consecutive_lines(previous, current)
74
- next if argument_name(current) >= argument_name(previous)
75
+ next if correct_order?(argument_name(previous), argument_name(current))
75
76
 
76
77
  register_offense(previous, current)
77
78
  end
@@ -34,6 +34,7 @@ module RuboCop
34
34
  extend AutoCorrector
35
35
 
36
36
  include RuboCop::GraphQL::SwapRange
37
+ include RuboCop::GraphQL::CompareOrder
37
38
 
38
39
  MSG = "Fields should be sorted in an alphabetical order within their "\
39
40
  "section. "\
@@ -51,7 +52,7 @@ module RuboCop
51
52
  def on_class(node)
52
53
  field_declarations(node).each_cons(2) do |previous, current|
53
54
  next unless consecutive_fields(previous, current)
54
- next if field_name(current) >= field_name(previous)
55
+ next if correct_order?(field_name(previous), field_name(current))
55
56
 
56
57
  register_offense(previous, current)
57
58
  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
  #
@@ -21,6 +21,7 @@ module RuboCop
21
21
  # field :name, String, "Name of the user", null: true, hash_key: :name
22
22
  #
23
23
  class UnnecessaryFieldAlias < Base
24
+ extend AutoCorrector
24
25
  include RuboCop::GraphQL::NodePattern
25
26
 
26
27
  MSG = "Unnecessary :%<kwarg>s configured"
@@ -32,7 +33,13 @@ module RuboCop
32
33
 
33
34
  if (unnecessary_kwarg = validate_kwargs(field))
34
35
  message = format(self.class::MSG, kwarg: unnecessary_kwarg)
35
- add_offense(node, message: message)
36
+ add_offense(node, message: message) do |corrector|
37
+ kwarg_node = node.arguments.last.pairs.find do |pair|
38
+ pair.key.value == unnecessary_kwarg.to_sym
39
+ end
40
+ corrector.remove_preceding(kwarg_node, 2)
41
+ corrector.remove(kwarg_node)
42
+ end
36
43
  end
37
44
  end
38
45
 
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module GraphQL
5
+ module CompareOrder
6
+ def correct_order?(previous, current)
7
+ # If Order config is provided, we should use it to determine the order
8
+ # Else, we should use alphabetical order
9
+ # e.g. "Order" => [
10
+ # "id",
11
+ # "/^id_.*$/",
12
+ # "/^.*_id$/",
13
+ # "everything-else",
14
+ # "/^(created|updated)_at$/"
15
+ # ]
16
+ if (order = cop_config["Order"])
17
+ # For each of previous and current, we should find the first matching order,
18
+ # checking 'everything-else' last
19
+ # If the order is the same, we should use alphabetical order
20
+ # If the order is different, we should use the order
21
+ previous_order = order_index(previous, order)
22
+ current_order = order_index(current, order)
23
+
24
+ if previous_order == current_order
25
+ previous <= current
26
+ else
27
+ previous_order < current_order
28
+ end
29
+ else
30
+ previous <= current
31
+ end
32
+ end
33
+
34
+ def order_index(field, order)
35
+ everything_else_index = order.length
36
+
37
+ order.each_with_index do |order_item, index|
38
+ if order_item == "everything-else"
39
+ everything_else_index = index
40
+ elsif order_item.start_with?("/") && order_item.end_with?("/") # is regex-like?
41
+ return index if field.match?(order_item[1..-2])
42
+ elsif field == order_item
43
+ return index
44
+ end
45
+ end
46
+
47
+ everything_else_index
48
+ end
49
+ end
50
+ end
51
+ end
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module GraphQL
5
5
  module Ext
6
6
  module SnakeCase
7
- SNAKE_CASE = /^[\da-z_]+[!?=]?$/.freeze
7
+ SNAKE_CASE = /^[\da-z_]+[!?=]?$/
8
8
 
9
9
  refine Symbol do
10
10
  def snake_case?
@@ -1,5 +1,5 @@
1
1
  module RuboCop
2
2
  module GraphQL
3
- VERSION = "1.1.1".freeze
3
+ VERSION = "1.3.0".freeze
4
4
  end
5
5
  end
@@ -7,6 +7,7 @@ require_relative "rubocop/graphql/ext/snake_case"
7
7
  require_relative "rubocop/graphql"
8
8
  require_relative "rubocop/graphql/version"
9
9
  require_relative "rubocop/graphql/inject"
10
+ require_relative "rubocop/graphql/compare_order"
10
11
  require_relative "rubocop/graphql/description_method"
11
12
  require_relative "rubocop/graphql/heredoc"
12
13
  require_relative "rubocop/graphql/node_pattern"
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.1.1
4
+ version: 1.3.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-03-31 00:00:00.000000000 Z
11
+ date: 2023-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -115,6 +115,7 @@ files:
115
115
  - lib/rubocop/graphql/argument/block.rb
116
116
  - lib/rubocop/graphql/argument/kwargs.rb
117
117
  - lib/rubocop/graphql/class.rb
118
+ - lib/rubocop/graphql/compare_order.rb
118
119
  - lib/rubocop/graphql/description_method.rb
119
120
  - lib/rubocop/graphql/ext/snake_case.rb
120
121
  - lib/rubocop/graphql/field.rb
@@ -143,7 +144,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
143
144
  requirements:
144
145
  - - ">="
145
146
  - !ruby/object:Gem::Version
146
- version: '2.5'
147
+ version: '3.0'
147
148
  required_rubygems_version: !ruby/object:Gem::Requirement
148
149
  requirements:
149
150
  - - ">="