rubocop-graphql 0.1.3 → 0.2.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 +4 -4
- data/config/default.yml +33 -0
- data/lib/rubocop-graphql.rb +7 -1
- data/lib/rubocop/cop/graphql/argument_description.rb +36 -0
- data/lib/rubocop/cop/graphql/argument_name.rb +39 -0
- data/lib/rubocop/cop/graphql/extract_input_type.rb +41 -0
- data/lib/rubocop/cop/graphql/extract_type.rb +98 -0
- data/lib/rubocop/cop/graphql/field_definitions.rb +46 -1
- data/lib/rubocop/cop/graphql/field_method.rb +21 -4
- data/lib/rubocop/cop/graphql/field_name.rb +39 -0
- data/lib/rubocop/cop/graphql_cops.rb +5 -0
- data/lib/rubocop/graphql/argument.rb +39 -0
- data/lib/rubocop/graphql/argument/block.rb +31 -0
- data/lib/rubocop/graphql/argument/kwargs.rb +32 -0
- data/lib/rubocop/graphql/ext/snake_case.rb +17 -0
- data/lib/rubocop/graphql/field.rb +23 -12
- data/lib/rubocop/graphql/field/block.rb +31 -0
- data/lib/rubocop/graphql/field/kwargs.rb +64 -0
- data/lib/rubocop/graphql/node_pattern.rb +8 -0
- data/lib/rubocop/graphql/version.rb +1 -1
- metadata +13 -3
- data/lib/rubocop/graphql/field_kwargs.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97a32c7f3e6a945161380f4d71afe27ad379af7ed6f4657cea6b73d42dae5213
|
4
|
+
data.tar.gz: a039ae1c957f91d596f5b834035401ad031f2cf8723701e708d192f29dfb6784
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a17ab56af1141ef437dff2e908845c3c9a7d95b86f7e97c329787f43da0aef67be691a1d4179486d4580f40bb4fdbf423354ef619f7135651c0dcbe683a756b2
|
7
|
+
data.tar.gz: d9fb15417d019a952424942e5d860387da2bb1cd61abbeec1626ca9c7b9c2dec485cbe26b9cba28cec88128a828bb3cd1d776a9f3bc333bfc019d2ef8989b4e6
|
data/config/default.yml
CHANGED
@@ -3,6 +3,16 @@ AllCops:
|
|
3
3
|
Patterns:
|
4
4
|
- "(?:^|/)graphql/"
|
5
5
|
|
6
|
+
GraphQL/ArgumentDescription:
|
7
|
+
Enabled: true
|
8
|
+
VersionAdded: '0.80'
|
9
|
+
Description: 'Ensures all arguments have a description'
|
10
|
+
|
11
|
+
GraphQL/ArgumentName:
|
12
|
+
Enabled: true
|
13
|
+
VersionAdded: '0.80'
|
14
|
+
Description: 'This cop checks whether argument names are snake_case'
|
15
|
+
|
6
16
|
GraphQL/ResolverMethodLength:
|
7
17
|
Enabled: true
|
8
18
|
VersionAdded: '0.80'
|
@@ -29,3 +39,26 @@ GraphQL/FieldMethod:
|
|
29
39
|
Enabled: true
|
30
40
|
VersionAdded: '0.80'
|
31
41
|
Description: 'Checks :method option is used for appropriate fields'
|
42
|
+
|
43
|
+
GraphQL/FieldName:
|
44
|
+
Enabled: true
|
45
|
+
VersionAdded: '0.80'
|
46
|
+
Description: 'This cop checks whether field names are snake_case'
|
47
|
+
|
48
|
+
GraphQL/ExtractInputType:
|
49
|
+
Enabled: true
|
50
|
+
VersionAdded: '0.80'
|
51
|
+
Description: 'Suggests using input type instead of many arguments'
|
52
|
+
MaxArguments: 2
|
53
|
+
|
54
|
+
GraphQL/ExtractType:
|
55
|
+
Enabled: true
|
56
|
+
VersionAdded: '0.80'
|
57
|
+
Description: 'Suggests extracting fields with common prefixes to the separate type'
|
58
|
+
MaxFields: 2
|
59
|
+
Prefixes:
|
60
|
+
- is
|
61
|
+
- with
|
62
|
+
- avg
|
63
|
+
- min
|
64
|
+
- max
|
data/lib/rubocop-graphql.rb
CHANGED
@@ -2,13 +2,19 @@
|
|
2
2
|
|
3
3
|
require "rubocop"
|
4
4
|
|
5
|
+
require_relative "rubocop/graphql/ext/snake_case"
|
6
|
+
|
5
7
|
require_relative "rubocop/graphql"
|
6
8
|
require_relative "rubocop/graphql/version"
|
7
9
|
require_relative "rubocop/graphql/inject"
|
8
10
|
require_relative "rubocop/graphql/node_pattern"
|
9
11
|
|
12
|
+
require_relative "rubocop/graphql/argument"
|
13
|
+
require_relative "rubocop/graphql/argument/block"
|
14
|
+
require_relative "rubocop/graphql/argument/kwargs"
|
10
15
|
require_relative "rubocop/graphql/field"
|
11
|
-
require_relative "rubocop/graphql/
|
16
|
+
require_relative "rubocop/graphql/field/block"
|
17
|
+
require_relative "rubocop/graphql/field/kwargs"
|
12
18
|
require_relative "rubocop/graphql/schema_member"
|
13
19
|
|
14
20
|
RuboCop::GraphQL::Inject.defaults!
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module GraphQL
|
6
|
+
# This cop checks if each field has a description.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # good
|
10
|
+
#
|
11
|
+
# class BanUser < BaseMutation
|
12
|
+
# argument :uuid, ID, required: true
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# # bad
|
16
|
+
#
|
17
|
+
# class BanUser < BaseMutation
|
18
|
+
# argument :uuid, ID, required: true, description: "UUID of the user to ban"
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
class ArgumentDescription < Cop
|
22
|
+
include RuboCop::GraphQL::NodePattern
|
23
|
+
|
24
|
+
MSG = "Missing argument description"
|
25
|
+
|
26
|
+
def on_send(node)
|
27
|
+
return unless argument?(node)
|
28
|
+
|
29
|
+
argument = RuboCop::GraphQL::Argument.new(node)
|
30
|
+
|
31
|
+
add_offense(node) unless argument.description
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module GraphQL
|
6
|
+
# This cop checks whether field names are snake_case.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # good
|
10
|
+
#
|
11
|
+
# class BanUser < BaseMutation
|
12
|
+
# argument :user_id, ID, required: true
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# # bad
|
16
|
+
#
|
17
|
+
# class BanUser < BaseMutation
|
18
|
+
# argument :userId, ID, required: true
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
class ArgumentName < Cop
|
22
|
+
include RuboCop::GraphQL::NodePattern
|
23
|
+
|
24
|
+
using RuboCop::GraphQL::Ext::SnakeCase
|
25
|
+
|
26
|
+
MSG = "Use snake_case for argument names"
|
27
|
+
|
28
|
+
def on_send(node)
|
29
|
+
return unless argument?(node)
|
30
|
+
|
31
|
+
argument = RuboCop::GraphQL::Argument.new(node)
|
32
|
+
return if argument.name.snake_case?
|
33
|
+
|
34
|
+
add_offense(node)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module GraphQL
|
6
|
+
class ExtractInputType < Cop
|
7
|
+
# This cop checks fields on common prefix groups
|
8
|
+
#
|
9
|
+
# # @example
|
10
|
+
# # good
|
11
|
+
#
|
12
|
+
# class UpdateUser < BaseMutation
|
13
|
+
# argument :uuid, ID, required: true
|
14
|
+
# argument :user_attributes, UserAttributesInputType
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # bad
|
18
|
+
#
|
19
|
+
# class UpdateUser < BaseMutation
|
20
|
+
# argument :uuid, ID, required: true
|
21
|
+
# argument :first_name, String, required: true
|
22
|
+
# argument :last_name, String, required: true
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
include RuboCop::GraphQL::NodePattern
|
26
|
+
|
27
|
+
MSG = "Consider moving arguments to a new input type"
|
28
|
+
|
29
|
+
def on_class(node)
|
30
|
+
schema_member = RuboCop::GraphQL::SchemaMember.new(node)
|
31
|
+
|
32
|
+
if (body = schema_member.body)
|
33
|
+
arguments = body.select { |node| argument?(node) }
|
34
|
+
|
35
|
+
add_offense(arguments.last) if arguments.count > cop_config["MaxArguments"]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module GraphQL
|
6
|
+
class ExtractType < Cop
|
7
|
+
# This cop checks fields on common prefix groups
|
8
|
+
#
|
9
|
+
# # @example
|
10
|
+
# # good
|
11
|
+
#
|
12
|
+
# class Types::UserType < Types::BaseObject
|
13
|
+
# field :registered_at, String, null: false
|
14
|
+
# field :contact, Types::ContactType, null: false
|
15
|
+
#
|
16
|
+
# def contact
|
17
|
+
# self
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# class Types::ContactType < Types::BaseObject
|
22
|
+
# field :phone, String, null: false
|
23
|
+
# field :first_name, String, null: false
|
24
|
+
# field :last_name, String, null: false
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# # bad
|
28
|
+
#
|
29
|
+
# class Types::UserType < Types::BaseObject
|
30
|
+
# field :registered_at, String, null: false
|
31
|
+
# field :contact_phone, String, null: false
|
32
|
+
# field :contact_first_name, String, null: false
|
33
|
+
# field :contact_last_name, String, null: false
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
include RuboCop::GraphQL::NodePattern
|
37
|
+
|
38
|
+
def on_class(node)
|
39
|
+
schema_member = RuboCop::GraphQL::SchemaMember.new(node)
|
40
|
+
|
41
|
+
if (body = schema_member.body)
|
42
|
+
check_fields_prefixes(body)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
MSG = "Consider moving %<field_names>s to a new type and adding the `%<prefix>s` field instead"
|
49
|
+
|
50
|
+
def check_fields_prefixes(body)
|
51
|
+
sorted_prefixes = fractured(body).sort_by { |k, _| k.size }.reverse
|
52
|
+
already_offenced_fields = []
|
53
|
+
|
54
|
+
sorted_prefixes.each do |prefix, fields|
|
55
|
+
fields -= already_offenced_fields
|
56
|
+
|
57
|
+
next if fields.count < cop_config["MaxFields"]
|
58
|
+
|
59
|
+
add_offense(
|
60
|
+
fields.last.node,
|
61
|
+
message: message(prefix, fields.map(&:name).join(", "))
|
62
|
+
)
|
63
|
+
|
64
|
+
already_offenced_fields += fields
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def fractured(body)
|
69
|
+
body.each_with_object({}) do |node, acc|
|
70
|
+
next unless field?(node)
|
71
|
+
|
72
|
+
field = RuboCop::GraphQL::Field.new(node)
|
73
|
+
next unless field.underscore_name.include?("_")
|
74
|
+
|
75
|
+
*prefixes, _ = field.underscore_name.split("_")
|
76
|
+
|
77
|
+
prefixes.each_with_object([]) do |prefix, prev_prefix|
|
78
|
+
prefix = (prev_prefix + [prefix]).join("_")
|
79
|
+
break if ignored_prefix?(prefix)
|
80
|
+
|
81
|
+
(acc[prefix] ||= []) << field
|
82
|
+
|
83
|
+
prev_prefix << prefix
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def message(prefix, field_names)
|
89
|
+
format(MSG, field_names: field_names, prefix: prefix)
|
90
|
+
end
|
91
|
+
|
92
|
+
def ignored_prefix?(word)
|
93
|
+
cop_config["Prefixes"].include?(word)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -47,6 +47,7 @@ module RuboCop
|
|
47
47
|
class FieldDefinitions < Cop
|
48
48
|
include ConfigurableEnforcedStyle
|
49
49
|
include RuboCop::GraphQL::NodePattern
|
50
|
+
include RuboCop::Cop::RangeHelp
|
50
51
|
|
51
52
|
def_node_matcher :field_kwargs, <<~PATTERN
|
52
53
|
(send nil? :field
|
@@ -74,12 +75,23 @@ module RuboCop
|
|
74
75
|
end
|
75
76
|
end
|
76
77
|
|
78
|
+
def autocorrect(node)
|
79
|
+
lambda do |corrector|
|
80
|
+
case style
|
81
|
+
when :define_resolver_after_definition
|
82
|
+
place_resolver_after_definitions(corrector, node)
|
83
|
+
when :group_definitions
|
84
|
+
group_field_declarations(corrector, node)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
77
89
|
private
|
78
90
|
|
79
91
|
GROUP_DEFS_MSG = "Group all field definitions together."
|
80
92
|
|
81
93
|
def check_grouped_field_declarations(body)
|
82
|
-
fields = body.select { |node|
|
94
|
+
fields = body.select { |node| field?(node) }
|
83
95
|
|
84
96
|
first_field = fields.first
|
85
97
|
|
@@ -90,6 +102,20 @@ module RuboCop
|
|
90
102
|
end
|
91
103
|
end
|
92
104
|
|
105
|
+
def group_field_declarations(corrector, node)
|
106
|
+
field = RuboCop::GraphQL::Field.new(node)
|
107
|
+
|
108
|
+
first_field = field.schema_member.body.find { |node|
|
109
|
+
field_definition?(node) || field_definition_with_body?(node)
|
110
|
+
}
|
111
|
+
|
112
|
+
source_to_insert = "\n" + indent(node) + node.source
|
113
|
+
corrector.insert_after(first_field.loc.expression, source_to_insert)
|
114
|
+
|
115
|
+
range = range_with_surrounding_space(range: node.loc.expression, side: :left)
|
116
|
+
corrector.remove(range)
|
117
|
+
end
|
118
|
+
|
93
119
|
RESOLVER_AFTER_FIELD_MSG = "Define resolver method after field definition."
|
94
120
|
|
95
121
|
def check_resolver_is_defined_after_definition(field)
|
@@ -108,6 +134,25 @@ module RuboCop
|
|
108
134
|
|
109
135
|
add_offense(field.node, message: RESOLVER_AFTER_FIELD_MSG)
|
110
136
|
end
|
137
|
+
|
138
|
+
def place_resolver_after_definitions(corrector, node)
|
139
|
+
field = RuboCop::GraphQL::Field.new(node)
|
140
|
+
|
141
|
+
method_definition = field.schema_member.find_method_definition(field.resolver_method_name)
|
142
|
+
|
143
|
+
field_definition = field_definition_with_body?(node.parent) ? node.parent : node
|
144
|
+
|
145
|
+
source_to_insert = indent(method_definition) + field_definition.source + "\n\n"
|
146
|
+
method_range = range_by_whole_lines(method_definition.loc.expression)
|
147
|
+
corrector.insert_before(method_range, source_to_insert)
|
148
|
+
|
149
|
+
range_to_remove = range_with_surrounding_space(range: field_definition.loc.expression, side: :left)
|
150
|
+
corrector.remove(range_to_remove)
|
151
|
+
end
|
152
|
+
|
153
|
+
def indent(node)
|
154
|
+
" " * node.location.column
|
155
|
+
end
|
111
156
|
end
|
112
157
|
end
|
113
158
|
end
|
@@ -25,6 +25,7 @@ module RuboCop
|
|
25
25
|
#
|
26
26
|
class FieldMethod < Cop
|
27
27
|
include RuboCop::GraphQL::NodePattern
|
28
|
+
include RuboCop::Cop::RangeHelp
|
28
29
|
|
29
30
|
def_node_matcher :method_to_use, <<~PATTERN
|
30
31
|
(def
|
@@ -42,12 +43,23 @@ module RuboCop
|
|
42
43
|
return unless field_definition?(node)
|
43
44
|
|
44
45
|
field = RuboCop::GraphQL::Field.new(node)
|
46
|
+
method_definition = suggest_method_name_for(field)
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
+
if (suggested_method_name = method_to_use(method_definition))
|
49
|
+
add_offense(node, message: message(suggested_method_name))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def autocorrect(node)
|
54
|
+
lambda do |corrector|
|
55
|
+
field = RuboCop::GraphQL::Field.new(node)
|
56
|
+
method_definition = suggest_method_name_for(field)
|
57
|
+
suggested_method_name = method_to_use(method_definition)
|
48
58
|
|
49
|
-
|
50
|
-
|
59
|
+
corrector.insert_after(node.loc.expression, ", method: :#{suggested_method_name}")
|
60
|
+
|
61
|
+
range = range_with_surrounding_space(range: method_definition.loc.expression, side: :left)
|
62
|
+
corrector.remove(range)
|
51
63
|
end
|
52
64
|
end
|
53
65
|
|
@@ -56,6 +68,11 @@ module RuboCop
|
|
56
68
|
def message(method_name)
|
57
69
|
format(MSG, method_name: method_name)
|
58
70
|
end
|
71
|
+
|
72
|
+
def suggest_method_name_for(field)
|
73
|
+
method_name = field.resolver_method_name
|
74
|
+
field.schema_member.find_method_definition(method_name)
|
75
|
+
end
|
59
76
|
end
|
60
77
|
end
|
61
78
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module GraphQL
|
6
|
+
# This cop checks whether field names are snake_case.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # good
|
10
|
+
#
|
11
|
+
# class UserType < BaseType
|
12
|
+
# field :first_name, String, null: true
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# # bad
|
16
|
+
#
|
17
|
+
# class UserType < BaseType
|
18
|
+
# field :firstName, String, null: true
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
class FieldName < Cop
|
22
|
+
include RuboCop::GraphQL::NodePattern
|
23
|
+
|
24
|
+
using RuboCop::GraphQL::Ext::SnakeCase
|
25
|
+
|
26
|
+
MSG = "Use snake_case for field names"
|
27
|
+
|
28
|
+
def on_send(node)
|
29
|
+
return unless field_definition?(node)
|
30
|
+
|
31
|
+
field = RuboCop::GraphQL::Field.new(node)
|
32
|
+
return if field.name.snake_case?
|
33
|
+
|
34
|
+
add_offense(node)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -2,7 +2,12 @@
|
|
2
2
|
|
3
3
|
require_relative "graphql/cop"
|
4
4
|
|
5
|
+
require_relative "graphql/argument_description"
|
6
|
+
require_relative "graphql/argument_name"
|
7
|
+
require_relative "graphql/extract_input_type"
|
8
|
+
require_relative "graphql/extract_type"
|
5
9
|
require_relative "graphql/field_definitions"
|
6
10
|
require_relative "graphql/field_description"
|
7
11
|
require_relative "graphql/field_method"
|
12
|
+
require_relative "graphql/field_name"
|
8
13
|
require_relative "graphql/resolver_method_length"
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module GraphQL
|
5
|
+
class Argument
|
6
|
+
extend RuboCop::NodePattern::Macros
|
7
|
+
|
8
|
+
def_node_matcher :argument_description, <<~PATTERN
|
9
|
+
(send nil? :argument _ _ (:str $_) ...)
|
10
|
+
PATTERN
|
11
|
+
|
12
|
+
def_node_matcher :argument_name, <<~PATTERN
|
13
|
+
(send nil? :argument (:sym $_) ...)
|
14
|
+
PATTERN
|
15
|
+
|
16
|
+
attr_reader :node
|
17
|
+
|
18
|
+
def initialize(node)
|
19
|
+
@node = node
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
@name ||= argument_name(@node)
|
24
|
+
end
|
25
|
+
|
26
|
+
def description
|
27
|
+
@description ||= argument_description(@node) || kwargs.description || block.description
|
28
|
+
end
|
29
|
+
|
30
|
+
def kwargs
|
31
|
+
@kwargs ||= Argument::Kwargs.new(@node)
|
32
|
+
end
|
33
|
+
|
34
|
+
def block
|
35
|
+
@block ||= Argument::Block.new(@node.parent)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module GraphQL
|
5
|
+
class Argument
|
6
|
+
class Block
|
7
|
+
extend RuboCop::NodePattern::Macros
|
8
|
+
|
9
|
+
def_node_matcher :argument_block, <<~PATTERN
|
10
|
+
(block
|
11
|
+
(send nil? :argument ...)
|
12
|
+
(args)
|
13
|
+
$...
|
14
|
+
)
|
15
|
+
PATTERN
|
16
|
+
|
17
|
+
def_node_matcher :description_kwarg?, <<~PATTERN
|
18
|
+
(send nil? :description (str ...))
|
19
|
+
PATTERN
|
20
|
+
|
21
|
+
def initialize(argument_node)
|
22
|
+
@nodes = argument_block(argument_node) || []
|
23
|
+
end
|
24
|
+
|
25
|
+
def description
|
26
|
+
@nodes.find { |kwarg| description_kwarg?(kwarg) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module GraphQL
|
5
|
+
class Argument
|
6
|
+
class Kwargs
|
7
|
+
extend RuboCop::NodePattern::Macros
|
8
|
+
|
9
|
+
def_node_matcher :argument_kwargs, <<~PATTERN
|
10
|
+
(send nil? :argument
|
11
|
+
...
|
12
|
+
(hash
|
13
|
+
$...
|
14
|
+
)
|
15
|
+
)
|
16
|
+
PATTERN
|
17
|
+
|
18
|
+
def_node_matcher :description_kwarg?, <<~PATTERN
|
19
|
+
(pair (sym :description) ...)
|
20
|
+
PATTERN
|
21
|
+
|
22
|
+
def initialize(argument_node)
|
23
|
+
@nodes = argument_kwargs(argument_node)
|
24
|
+
end
|
25
|
+
|
26
|
+
def description
|
27
|
+
@nodes.find { |kwarg| description_kwarg?(kwarg) }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -8,19 +8,15 @@ module RuboCop
|
|
8
8
|
|
9
9
|
def_delegators :@node, :sibling_index, :parent
|
10
10
|
|
11
|
-
def_node_matcher :field_kwargs, <<~PATTERN
|
12
|
-
(send nil? :field
|
13
|
-
...
|
14
|
-
(hash
|
15
|
-
$...
|
16
|
-
)
|
17
|
-
)
|
18
|
-
PATTERN
|
19
|
-
|
20
11
|
def_node_matcher :field_name, <<~PATTERN
|
21
12
|
(send nil? :field (:sym $_) ...)
|
22
13
|
PATTERN
|
23
14
|
|
15
|
+
def_node_matcher :field_with_body_name, <<~PATTERN
|
16
|
+
(block
|
17
|
+
(send nil? :field (:sym $_) ...)...)
|
18
|
+
PATTERN
|
19
|
+
|
24
20
|
def_node_matcher :field_description, <<~PATTERN
|
25
21
|
(send nil? :field _ _ (:str $_) ...)
|
26
22
|
PATTERN
|
@@ -32,11 +28,22 @@ module RuboCop
|
|
32
28
|
end
|
33
29
|
|
34
30
|
def name
|
35
|
-
field_name(@node)
|
31
|
+
@name ||= field_name(@node) || field_with_body_name(@node)
|
32
|
+
end
|
33
|
+
|
34
|
+
def underscore_name
|
35
|
+
@underscore_name ||= begin
|
36
|
+
word = name.to_s.dup
|
37
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
38
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
39
|
+
word.tr!("-", "_")
|
40
|
+
word.downcase!
|
41
|
+
word
|
42
|
+
end
|
36
43
|
end
|
37
44
|
|
38
45
|
def description
|
39
|
-
field_description(@node)
|
46
|
+
@description ||= field_description(@node) || kwargs.description || block.description
|
40
47
|
end
|
41
48
|
|
42
49
|
def resolver_method_name
|
@@ -44,7 +51,11 @@ module RuboCop
|
|
44
51
|
end
|
45
52
|
|
46
53
|
def kwargs
|
47
|
-
@kwargs ||=
|
54
|
+
@kwargs ||= Field::Kwargs.new(@node)
|
55
|
+
end
|
56
|
+
|
57
|
+
def block
|
58
|
+
@block ||= Field::Block.new(@node.parent)
|
48
59
|
end
|
49
60
|
|
50
61
|
def schema_member
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module GraphQL
|
5
|
+
class Field
|
6
|
+
class Block
|
7
|
+
extend RuboCop::NodePattern::Macros
|
8
|
+
|
9
|
+
def_node_matcher :field_block, <<~PATTERN
|
10
|
+
(block
|
11
|
+
(send nil? :field ...)
|
12
|
+
(args)
|
13
|
+
$...
|
14
|
+
)
|
15
|
+
PATTERN
|
16
|
+
|
17
|
+
def_node_matcher :description_kwarg?, <<~PATTERN
|
18
|
+
(send nil? :description (str ...))
|
19
|
+
PATTERN
|
20
|
+
|
21
|
+
def initialize(field_node)
|
22
|
+
@nodes = field_block(field_node) || []
|
23
|
+
end
|
24
|
+
|
25
|
+
def description
|
26
|
+
@nodes.find { |kwarg| description_kwarg?(kwarg) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module GraphQL
|
5
|
+
class Field
|
6
|
+
class Kwargs
|
7
|
+
extend RuboCop::NodePattern::Macros
|
8
|
+
|
9
|
+
def_node_matcher :field_kwargs, <<~PATTERN
|
10
|
+
(send nil? :field
|
11
|
+
...
|
12
|
+
(hash
|
13
|
+
$...
|
14
|
+
)
|
15
|
+
)
|
16
|
+
PATTERN
|
17
|
+
|
18
|
+
def_node_matcher :resolver_kwarg?, <<~PATTERN
|
19
|
+
(pair (sym :resolver) ...)
|
20
|
+
PATTERN
|
21
|
+
|
22
|
+
def_node_matcher :method_kwarg?, <<~PATTERN
|
23
|
+
(pair (sym :method) ...)
|
24
|
+
PATTERN
|
25
|
+
|
26
|
+
def_node_matcher :hash_key_kwarg?, <<~PATTERN
|
27
|
+
(pair (sym :hash_key) ...)
|
28
|
+
PATTERN
|
29
|
+
|
30
|
+
def_node_matcher :description_kwarg?, <<~PATTERN
|
31
|
+
(pair (sym :description) ...)
|
32
|
+
PATTERN
|
33
|
+
|
34
|
+
def_node_matcher :resolver_method_option, <<~PATTERN
|
35
|
+
(pair (sym :resolver_method) (sym $...))
|
36
|
+
PATTERN
|
37
|
+
|
38
|
+
def initialize(field_node)
|
39
|
+
@nodes = field_kwargs(field_node)
|
40
|
+
end
|
41
|
+
|
42
|
+
def resolver
|
43
|
+
@nodes.find { |kwarg| resolver_kwarg?(kwarg) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def method
|
47
|
+
@nodes.find { |kwarg| method_kwarg?(kwarg) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def hash_key
|
51
|
+
@nodes.find { |kwarg| hash_key_kwarg?(kwarg) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def description
|
55
|
+
@nodes.find { |kwarg| description_kwarg?(kwarg) }
|
56
|
+
end
|
57
|
+
|
58
|
+
def resolver_method_name
|
59
|
+
@resolver_method_name ||= @nodes.flat_map { |kwarg| resolver_method_option(kwarg) }.compact.first
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
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: 0.
|
4
|
+
version: 0.2.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: 2020-
|
11
|
+
date: 2020-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -77,15 +77,25 @@ files:
|
|
77
77
|
- README.md
|
78
78
|
- config/default.yml
|
79
79
|
- lib/rubocop-graphql.rb
|
80
|
+
- lib/rubocop/cop/graphql/argument_description.rb
|
81
|
+
- lib/rubocop/cop/graphql/argument_name.rb
|
80
82
|
- lib/rubocop/cop/graphql/cop.rb
|
83
|
+
- lib/rubocop/cop/graphql/extract_input_type.rb
|
84
|
+
- lib/rubocop/cop/graphql/extract_type.rb
|
81
85
|
- lib/rubocop/cop/graphql/field_definitions.rb
|
82
86
|
- lib/rubocop/cop/graphql/field_description.rb
|
83
87
|
- lib/rubocop/cop/graphql/field_method.rb
|
88
|
+
- lib/rubocop/cop/graphql/field_name.rb
|
84
89
|
- lib/rubocop/cop/graphql/resolver_method_length.rb
|
85
90
|
- lib/rubocop/cop/graphql_cops.rb
|
86
91
|
- lib/rubocop/graphql.rb
|
92
|
+
- lib/rubocop/graphql/argument.rb
|
93
|
+
- lib/rubocop/graphql/argument/block.rb
|
94
|
+
- lib/rubocop/graphql/argument/kwargs.rb
|
95
|
+
- lib/rubocop/graphql/ext/snake_case.rb
|
87
96
|
- lib/rubocop/graphql/field.rb
|
88
|
-
- lib/rubocop/graphql/
|
97
|
+
- lib/rubocop/graphql/field/block.rb
|
98
|
+
- lib/rubocop/graphql/field/kwargs.rb
|
89
99
|
- lib/rubocop/graphql/inject.rb
|
90
100
|
- lib/rubocop/graphql/node_pattern.rb
|
91
101
|
- lib/rubocop/graphql/schema_member.rb
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module GraphQL
|
5
|
-
class FieldKwargs
|
6
|
-
extend RuboCop::NodePattern::Macros
|
7
|
-
|
8
|
-
def_node_matcher :resolver_kwarg?, <<~PATTERN
|
9
|
-
(pair (sym :resolver) ...)
|
10
|
-
PATTERN
|
11
|
-
|
12
|
-
def_node_matcher :method_kwarg?, <<~PATTERN
|
13
|
-
(pair (sym :method) ...)
|
14
|
-
PATTERN
|
15
|
-
|
16
|
-
def_node_matcher :hash_key_kwarg?, <<~PATTERN
|
17
|
-
(pair (sym :hash_key) ...)
|
18
|
-
PATTERN
|
19
|
-
|
20
|
-
def_node_matcher :resolver_method_option, <<~PATTERN
|
21
|
-
(pair (sym :resolver_method) (sym $...))
|
22
|
-
PATTERN
|
23
|
-
|
24
|
-
def initialize(nodes)
|
25
|
-
@nodes = nodes
|
26
|
-
end
|
27
|
-
|
28
|
-
def resolver
|
29
|
-
@nodes.find { |kwarg| resolver_kwarg?(kwarg) }
|
30
|
-
end
|
31
|
-
|
32
|
-
def method
|
33
|
-
@nodes.find { |kwarg| method_kwarg?(kwarg) }
|
34
|
-
end
|
35
|
-
|
36
|
-
def hash_key
|
37
|
-
@nodes.find { |kwarg| hash_key_kwarg?(kwarg) }
|
38
|
-
end
|
39
|
-
|
40
|
-
def resolver_method_name
|
41
|
-
@resolver_method_name ||= @nodes.flat_map { |kwarg| resolver_method_option(kwarg) }.compact.first
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|