yapi_check 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +61 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +242 -0
- data/README.md +114 -0
- data/README.zh-CN.md +110 -0
- data/Rakefile +14 -0
- data/bin/console +13 -0
- data/bin/setup +8 -0
- data/lib/yapi_check/config.rb +18 -0
- data/lib/yapi_check/executor.rb +241 -0
- data/lib/yapi_check/tasks.rb +67 -0
- data/lib/yapi_check/version.rb +3 -0
- data/lib/yapi_check/yapi_params.rb +5 -0
- data/lib/yapi_check.rb +12 -0
- data/sig/yapi_check.rbs +4 -0
- metadata +136 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 20968fe1514e86325f979ba7041f82c75db592f74905978e7876644b3d217fd1
|
4
|
+
data.tar.gz: c65b430731996baf54cabe776b6d497933052d7cbcb30fd30728bf2705e2bb13
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 75de9664e3764fb17c641094430000afff2cf1e8a953283dd7c8cba9eba650d090719746f2af0be324f6ae79e457a9cdd0293e98e6c6706b95426c81e81ab490
|
7
|
+
data.tar.gz: f9c0be6dc4b99c10ad8937b72e235b26e942c925e0e60ac91b6e151675fe23e6320c8b2d489187c5cd39746ed12630b2f58a542f4b803e54b57b22e22a949507
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 3.0
|
3
|
+
NewCops: enable
|
4
|
+
Exclude:
|
5
|
+
- db/schema.rb
|
6
|
+
- bin/**
|
7
|
+
SuggestExtensions: false
|
8
|
+
Style/RedundantReturn:
|
9
|
+
Enabled: false
|
10
|
+
Style/NumericPredicate:
|
11
|
+
Enabled: false
|
12
|
+
Style/FrozenStringLiteralComment:
|
13
|
+
Enabled: false
|
14
|
+
Style/Documentation:
|
15
|
+
Enabled: false
|
16
|
+
Style/AsciiComments:
|
17
|
+
Enabled: false
|
18
|
+
Style/ClassAndModuleChildren:
|
19
|
+
Enabled: false
|
20
|
+
Layout/LineLength:
|
21
|
+
Enabled: false
|
22
|
+
Metrics/MethodLength:
|
23
|
+
Max: 150
|
24
|
+
Metrics/CyclomaticComplexity:
|
25
|
+
Max: 60
|
26
|
+
Metrics/ClassLength:
|
27
|
+
Max: 410
|
28
|
+
Metrics/BlockLength:
|
29
|
+
Enabled: false
|
30
|
+
Naming/AccessorMethodName:
|
31
|
+
Enabled: false
|
32
|
+
Metrics/AbcSize:
|
33
|
+
Enabled: false
|
34
|
+
Metrics/ParameterLists:
|
35
|
+
Max: 14
|
36
|
+
Style/FormatStringToken:
|
37
|
+
Enabled: false
|
38
|
+
Style/FormatString:
|
39
|
+
Enabled: false
|
40
|
+
Naming/VariableNumber:
|
41
|
+
Enabled: false
|
42
|
+
Style/GuardClause:
|
43
|
+
Enabled: false
|
44
|
+
Metrics/PerceivedComplexity:
|
45
|
+
Enabled: false
|
46
|
+
Style/ConditionalAssignment:
|
47
|
+
Enabled: false
|
48
|
+
Metrics/BlockNesting:
|
49
|
+
Max: 4
|
50
|
+
Style/CaseLikeIf:
|
51
|
+
Enabled: false
|
52
|
+
Lint/SuppressedException:
|
53
|
+
Enabled: false
|
54
|
+
Style/NumericLiterals:
|
55
|
+
Enabled: false
|
56
|
+
Lint/DuplicateBranch:
|
57
|
+
Enabled: false
|
58
|
+
Style/HashSyntax:
|
59
|
+
Enabled: false
|
60
|
+
Style/WordArray:
|
61
|
+
Enabled: false
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
yapi_check (1.0.0)
|
5
|
+
http (>= 3.0)
|
6
|
+
method_source (~> 1.0)
|
7
|
+
rails (>= 5.2)
|
8
|
+
railties (>= 4.0)
|
9
|
+
rake
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
actioncable (7.1.3.2)
|
15
|
+
actionpack (= 7.1.3.2)
|
16
|
+
activesupport (= 7.1.3.2)
|
17
|
+
nio4r (~> 2.0)
|
18
|
+
websocket-driver (>= 0.6.1)
|
19
|
+
zeitwerk (~> 2.6)
|
20
|
+
actionmailbox (7.1.3.2)
|
21
|
+
actionpack (= 7.1.3.2)
|
22
|
+
activejob (= 7.1.3.2)
|
23
|
+
activerecord (= 7.1.3.2)
|
24
|
+
activestorage (= 7.1.3.2)
|
25
|
+
activesupport (= 7.1.3.2)
|
26
|
+
mail (>= 2.7.1)
|
27
|
+
net-imap
|
28
|
+
net-pop
|
29
|
+
net-smtp
|
30
|
+
actionmailer (7.1.3.2)
|
31
|
+
actionpack (= 7.1.3.2)
|
32
|
+
actionview (= 7.1.3.2)
|
33
|
+
activejob (= 7.1.3.2)
|
34
|
+
activesupport (= 7.1.3.2)
|
35
|
+
mail (~> 2.5, >= 2.5.4)
|
36
|
+
net-imap
|
37
|
+
net-pop
|
38
|
+
net-smtp
|
39
|
+
rails-dom-testing (~> 2.2)
|
40
|
+
actionpack (7.1.3.2)
|
41
|
+
actionview (= 7.1.3.2)
|
42
|
+
activesupport (= 7.1.3.2)
|
43
|
+
nokogiri (>= 1.8.5)
|
44
|
+
racc
|
45
|
+
rack (>= 2.2.4)
|
46
|
+
rack-session (>= 1.0.1)
|
47
|
+
rack-test (>= 0.6.3)
|
48
|
+
rails-dom-testing (~> 2.2)
|
49
|
+
rails-html-sanitizer (~> 1.6)
|
50
|
+
actiontext (7.1.3.2)
|
51
|
+
actionpack (= 7.1.3.2)
|
52
|
+
activerecord (= 7.1.3.2)
|
53
|
+
activestorage (= 7.1.3.2)
|
54
|
+
activesupport (= 7.1.3.2)
|
55
|
+
globalid (>= 0.6.0)
|
56
|
+
nokogiri (>= 1.8.5)
|
57
|
+
actionview (7.1.3.2)
|
58
|
+
activesupport (= 7.1.3.2)
|
59
|
+
builder (~> 3.1)
|
60
|
+
erubi (~> 1.11)
|
61
|
+
rails-dom-testing (~> 2.2)
|
62
|
+
rails-html-sanitizer (~> 1.6)
|
63
|
+
activejob (7.1.3.2)
|
64
|
+
activesupport (= 7.1.3.2)
|
65
|
+
globalid (>= 0.3.6)
|
66
|
+
activemodel (7.1.3.2)
|
67
|
+
activesupport (= 7.1.3.2)
|
68
|
+
activerecord (7.1.3.2)
|
69
|
+
activemodel (= 7.1.3.2)
|
70
|
+
activesupport (= 7.1.3.2)
|
71
|
+
timeout (>= 0.4.0)
|
72
|
+
activestorage (7.1.3.2)
|
73
|
+
actionpack (= 7.1.3.2)
|
74
|
+
activejob (= 7.1.3.2)
|
75
|
+
activerecord (= 7.1.3.2)
|
76
|
+
activesupport (= 7.1.3.2)
|
77
|
+
marcel (~> 1.0)
|
78
|
+
activesupport (7.1.3.2)
|
79
|
+
base64
|
80
|
+
bigdecimal
|
81
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
82
|
+
connection_pool (>= 2.2.5)
|
83
|
+
drb
|
84
|
+
i18n (>= 1.6, < 2)
|
85
|
+
minitest (>= 5.1)
|
86
|
+
mutex_m
|
87
|
+
tzinfo (~> 2.0)
|
88
|
+
addressable (2.8.6)
|
89
|
+
public_suffix (>= 2.0.2, < 6.0)
|
90
|
+
ast (2.4.2)
|
91
|
+
base64 (0.2.0)
|
92
|
+
bigdecimal (3.1.6)
|
93
|
+
builder (3.2.4)
|
94
|
+
concurrent-ruby (1.2.3)
|
95
|
+
connection_pool (2.4.1)
|
96
|
+
crass (1.0.6)
|
97
|
+
date (3.3.4)
|
98
|
+
domain_name (0.6.20240107)
|
99
|
+
drb (2.2.1)
|
100
|
+
erubi (1.12.0)
|
101
|
+
ffi (1.16.3)
|
102
|
+
ffi-compiler (1.0.1)
|
103
|
+
ffi (>= 1.0.0)
|
104
|
+
rake
|
105
|
+
globalid (1.2.1)
|
106
|
+
activesupport (>= 6.1)
|
107
|
+
http (5.2.0)
|
108
|
+
addressable (~> 2.8)
|
109
|
+
base64 (~> 0.1)
|
110
|
+
http-cookie (~> 1.0)
|
111
|
+
http-form_data (~> 2.2)
|
112
|
+
llhttp-ffi (~> 0.5.0)
|
113
|
+
http-cookie (1.0.5)
|
114
|
+
domain_name (~> 0.5)
|
115
|
+
http-form_data (2.3.0)
|
116
|
+
i18n (1.14.3)
|
117
|
+
concurrent-ruby (~> 1.0)
|
118
|
+
racc (~> 1.7)
|
119
|
+
io-console (0.7.2)
|
120
|
+
irb (1.11.2)
|
121
|
+
rdoc
|
122
|
+
reline (>= 0.4.2)
|
123
|
+
json (2.7.1)
|
124
|
+
language_server-protocol (3.17.0.3)
|
125
|
+
llhttp-ffi (0.5.0)
|
126
|
+
ffi-compiler (~> 1.0)
|
127
|
+
rake (~> 13.0)
|
128
|
+
loofah (2.22.0)
|
129
|
+
crass (~> 1.0.2)
|
130
|
+
nokogiri (>= 1.12.0)
|
131
|
+
mail (2.8.1)
|
132
|
+
mini_mime (>= 0.1.1)
|
133
|
+
net-imap
|
134
|
+
net-pop
|
135
|
+
net-smtp
|
136
|
+
marcel (1.0.4)
|
137
|
+
method_source (1.0.0)
|
138
|
+
mini_mime (1.1.5)
|
139
|
+
minitest (5.22.2)
|
140
|
+
mutex_m (0.2.0)
|
141
|
+
net-imap (0.4.10)
|
142
|
+
date
|
143
|
+
net-protocol
|
144
|
+
net-pop (0.1.2)
|
145
|
+
net-protocol
|
146
|
+
net-protocol (0.2.2)
|
147
|
+
timeout
|
148
|
+
net-smtp (0.4.0.1)
|
149
|
+
net-protocol
|
150
|
+
nio4r (2.7.0)
|
151
|
+
nokogiri (1.16.2-x86_64-darwin)
|
152
|
+
racc (~> 1.4)
|
153
|
+
parallel (1.24.0)
|
154
|
+
parser (3.3.0.5)
|
155
|
+
ast (~> 2.4.1)
|
156
|
+
racc
|
157
|
+
psych (5.1.2)
|
158
|
+
stringio
|
159
|
+
public_suffix (5.0.4)
|
160
|
+
racc (1.7.3)
|
161
|
+
rack (3.0.9.1)
|
162
|
+
rack-session (2.0.0)
|
163
|
+
rack (>= 3.0.0)
|
164
|
+
rack-test (2.1.0)
|
165
|
+
rack (>= 1.3)
|
166
|
+
rackup (2.1.0)
|
167
|
+
rack (>= 3)
|
168
|
+
webrick (~> 1.8)
|
169
|
+
rails (7.1.3.2)
|
170
|
+
actioncable (= 7.1.3.2)
|
171
|
+
actionmailbox (= 7.1.3.2)
|
172
|
+
actionmailer (= 7.1.3.2)
|
173
|
+
actionpack (= 7.1.3.2)
|
174
|
+
actiontext (= 7.1.3.2)
|
175
|
+
actionview (= 7.1.3.2)
|
176
|
+
activejob (= 7.1.3.2)
|
177
|
+
activemodel (= 7.1.3.2)
|
178
|
+
activerecord (= 7.1.3.2)
|
179
|
+
activestorage (= 7.1.3.2)
|
180
|
+
activesupport (= 7.1.3.2)
|
181
|
+
bundler (>= 1.15.0)
|
182
|
+
railties (= 7.1.3.2)
|
183
|
+
rails-dom-testing (2.2.0)
|
184
|
+
activesupport (>= 5.0.0)
|
185
|
+
minitest
|
186
|
+
nokogiri (>= 1.6)
|
187
|
+
rails-html-sanitizer (1.6.0)
|
188
|
+
loofah (~> 2.21)
|
189
|
+
nokogiri (~> 1.14)
|
190
|
+
railties (7.1.3.2)
|
191
|
+
actionpack (= 7.1.3.2)
|
192
|
+
activesupport (= 7.1.3.2)
|
193
|
+
irb
|
194
|
+
rackup (>= 1.0.0)
|
195
|
+
rake (>= 12.2)
|
196
|
+
thor (~> 1.0, >= 1.2.2)
|
197
|
+
zeitwerk (~> 2.6)
|
198
|
+
rainbow (3.1.1)
|
199
|
+
rake (13.1.0)
|
200
|
+
rdoc (6.6.2)
|
201
|
+
psych (>= 4.0.0)
|
202
|
+
regexp_parser (2.9.0)
|
203
|
+
reline (0.4.3)
|
204
|
+
io-console (~> 0.5)
|
205
|
+
rexml (3.2.6)
|
206
|
+
rubocop (1.60.2)
|
207
|
+
json (~> 2.3)
|
208
|
+
language_server-protocol (>= 3.17.0)
|
209
|
+
parallel (~> 1.10)
|
210
|
+
parser (>= 3.3.0.2)
|
211
|
+
rainbow (>= 2.2.2, < 4.0)
|
212
|
+
regexp_parser (>= 1.8, < 3.0)
|
213
|
+
rexml (>= 3.2.5, < 4.0)
|
214
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
215
|
+
ruby-progressbar (~> 1.7)
|
216
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
217
|
+
rubocop-ast (1.31.1)
|
218
|
+
parser (>= 3.3.0.4)
|
219
|
+
ruby-progressbar (1.13.0)
|
220
|
+
stringio (3.1.0)
|
221
|
+
thor (1.3.1)
|
222
|
+
timeout (0.4.1)
|
223
|
+
tzinfo (2.0.6)
|
224
|
+
concurrent-ruby (~> 1.0)
|
225
|
+
unicode-display_width (2.5.0)
|
226
|
+
webrick (1.8.1)
|
227
|
+
websocket-driver (0.7.6)
|
228
|
+
websocket-extensions (>= 0.1.0)
|
229
|
+
websocket-extensions (0.1.5)
|
230
|
+
zeitwerk (2.6.13)
|
231
|
+
|
232
|
+
PLATFORMS
|
233
|
+
x86_64-darwin
|
234
|
+
|
235
|
+
DEPENDENCIES
|
236
|
+
minitest (~> 5.0)
|
237
|
+
rake (~> 13.0)
|
238
|
+
rubocop (~> 1.21)
|
239
|
+
yapi_check!
|
240
|
+
|
241
|
+
BUNDLED WITH
|
242
|
+
2.5.6
|
data/README.md
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# YapiCheck
|
2
|
+
|
3
|
+
[en](./README.md) | [zh-CN](./README.zh-CN.md)
|
4
|
+
|
5
|
+
> YAPI is an excellent tool for managing API documentation, but maintaining consistency between the API documentation and code can be challenging. Instead of relying on manual recognition, let this tool automate the process for you.
|
6
|
+
|
7
|
+
This is a tool for checking the consistency and conformity between YAPI API documentation and code, ensuring strong consistency and adherence to standards.
|
8
|
+
|
9
|
+
## Key Features
|
10
|
+
|
11
|
+
### 1. Request Parameter Check
|
12
|
+
+ Scans the source code of actions, captures the lucky_param parameters of actions, and matches them with the input metadata of YAPI documentation.
|
13
|
+
+ Supports mandatory and optional validation
|
14
|
+
+ JSON parameters support type validation, including String, Float, and Integer types
|
15
|
+
+ Parameter checks require each field to be on a separate line, like:
|
16
|
+
```ruby
|
17
|
+
required(:name, :String) # Name
|
18
|
+
required(:phone, :Integer) # Phone number
|
19
|
+
required(:height, :Float) # Height
|
20
|
+
optional(:email, :Email) # Email
|
21
|
+
optional(:tags, :ArrayJSON) # Tags
|
22
|
+
```
|
23
|
+
### 2. Response Parameter Check
|
24
|
+
+ Matches Jbuilder source code with the output metadata of YAPI documentation.
|
25
|
+
+ Supports sub-views
|
26
|
+
+ Supports paths relative to the root directory or the current file directory
|
27
|
+
+ Action names must match the Jbuilder file names
|
28
|
+
+ Output requires each returned field to be on a separate line
|
29
|
+
+ Output requires mandatory type conversion:
|
30
|
+
+ Strings: Recognized using to_s, json.attr_name ... to_s
|
31
|
+
+ Integers: Recognized using to_i, json.attr_name ... to_i
|
32
|
+
+ Floats: Recognized using to_f, json.attr_name ... to_f
|
33
|
+
+ Arrays: Recognized using to_a or do, json.attr_name ... each do
|
34
|
+
+ Hashes: Recognized using to_h or do, json.attr_name each do
|
35
|
+
```ruby
|
36
|
+
json.user do
|
37
|
+
json.name user.name.to_s
|
38
|
+
json.phone user.phone.to_i
|
39
|
+
json.height user.height.to_f
|
40
|
+
json.email user.email.to_s
|
41
|
+
json.tags user.tags.to_a
|
42
|
+
end
|
43
|
+
```
|
44
|
+
+ Does not support boolean types; use integers instead
|
45
|
+
+ Attributes must be included in the data object, such as: {"code":200, "data":{}}
|
46
|
+
### 3. Batch Check
|
47
|
+
+ Supports checking all interfaces of a single project
|
48
|
+
+ Supports checking a single interface
|
49
|
+
+ Supports checking interfaces under a single tag
|
50
|
+
|
51
|
+
## Usage Instructions
|
52
|
+
|
53
|
+
1. Add the following line to your Rails project's Gemfile:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
gem 'yapi_check'
|
57
|
+
```
|
58
|
+
|
59
|
+
2. Run bundle install:
|
60
|
+
|
61
|
+
```shell
|
62
|
+
$ bundle install
|
63
|
+
```
|
64
|
+
|
65
|
+
3. Insert the following code into your project's Rakefile:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
require 'yapi_check/tasks'
|
69
|
+
ENV['YAPI_PROJECT_TOKEN'] = 'THE_TOKEN_FROM_YOUR_YAPI_PROJECT' # YAPI project unique identifier (required), recommended to configure in the project. You can find this token in the YAPI project settings.
|
70
|
+
ENV['YAPI_PROJECT_DOMAIN'] = 'http://YOUR_YAPI_WEBSITE' # YAPI project domain, recommended to configure on your local machine to avoid changes in ~/.bashrc or ~/.zshrc
|
71
|
+
ENV['YAPI_API_PREFIX'] = '' # YAPI project API prefix, can be set to '', defaults to /api/v1 if not set
|
72
|
+
```
|
73
|
+
|
74
|
+
4. Run YAPI check:
|
75
|
+
Note: If using zsh, install the rake plugin in ~/.zshrc to support special syntax plugins=(... rake)
|
76
|
+
|
77
|
+
```shell
|
78
|
+
# Full check
|
79
|
+
$ bundle exec rake yapi:check
|
80
|
+
# or
|
81
|
+
$ rails yapi:check
|
82
|
+
|
83
|
+
# Check a single interface
|
84
|
+
$ bundle exec rake yapi:check[/healthy_lives/exit_healthy_life]
|
85
|
+
# or
|
86
|
+
$ noglob rails yapi:check[/healthy_lives/exit_healthy_life]
|
87
|
+
# or
|
88
|
+
$ rails 'yapi:check[/healthy_lives/exit_healthy_life]'
|
89
|
+
|
90
|
+
# Check a single tag
|
91
|
+
$ bundle exec rake yapi:check[,3.3.0]
|
92
|
+
# or
|
93
|
+
$ noglob rails yapi:check[,3.3.0]
|
94
|
+
# or
|
95
|
+
$ rails 'yapi:check[,3.3.0]'
|
96
|
+
```
|
97
|
+
|
98
|
+
## Notes
|
99
|
+
|
100
|
+
This tool is only for Rails projects. Request parameter checks heavily depend on [lucky_param](https://github.com/shootingfly/lucky_param), and response parameter checks heavily depend on [Jbuilder](https://github.com/rails/jbuilder).
|
101
|
+
|
102
|
+
## Contributing
|
103
|
+
|
104
|
+
1. Fork it ( https://github.com/shootingfly/yapi_check/fork )
|
105
|
+
2. Create your feature branch (git checkout -b my-new-feature)
|
106
|
+
3. Make your changes
|
107
|
+
4. Run `ruby test/yapi_check_test.rb` to run the tests
|
108
|
+
5. Commit your changes (git commit -am 'Add some feature')
|
109
|
+
6. Push to the branch (git push origin my-new-feature)
|
110
|
+
7. Create a new Pull Request
|
111
|
+
|
112
|
+
## License
|
113
|
+
|
114
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/README.zh-CN.md
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# YapiCheck
|
2
|
+
|
3
|
+
[en](./README.md) | [zh-CN](./README.zh-CN.md)
|
4
|
+
|
5
|
+
> YAPI是一款非常棒的接口文档管理工具, 但保持接口文档与代码一致性是一个难题, 与其通过人眼识别, 不如让工具自动化帮你处理
|
6
|
+
|
7
|
+
这是一款用于核对YAPI接口文档与代码的工具, 具有强一致性与规范性.
|
8
|
+
|
9
|
+
## 主要功能
|
10
|
+
### 1. 请求参数检查
|
11
|
+
+ 通过扫描action的源代码,并捕获action的lucky_param参数,与YAPI文档的入参元数据进行匹配
|
12
|
+
+ 支持必填性与非必填性验证
|
13
|
+
+ 其中JSON参数支持类型验证, 支持判断String, Float, Integer三种类型
|
14
|
+
+ 参数检测要求每个字段都单独成行, 如
|
15
|
+
```ruby
|
16
|
+
required(:name, :String) # 姓名
|
17
|
+
required(:phone, :Integer) # 手机号
|
18
|
+
required(:height, :Float) # 身高
|
19
|
+
optional(:email, :Email) # 邮箱
|
20
|
+
optional(:tags, :ArrayJSON) # 标签
|
21
|
+
```
|
22
|
+
### 2. 响应参数检查
|
23
|
+
+ 通过扫描jbuilder源码,与YAPI文档的出参元数据进行匹配
|
24
|
+
+ 支持子视图
|
25
|
+
+ 支持使用相对根目录或相对当前文件目录的路径
|
26
|
+
+ action名称必须与jbuilder文件名保持一致
|
27
|
+
+ 出参要求每个返回的字段都单独成行
|
28
|
+
+ 出参要求强制类型转化:
|
29
|
+
+ 字符串: 使用to_s识别, json.attr_name ... to_s识别
|
30
|
+
+ 整型: 使用to_i识别, json.attr_name ... to_i识别
|
31
|
+
+ 浮点数: 使用to_f识别, json.attr_name ... to_f识别
|
32
|
+
+ 数组: 使用to_a识别或do识别, json.attr_name ... each do识别
|
33
|
+
+ 字典: 使用to_h识别或do识别, json.attr_name each do识别
|
34
|
+
```ruby
|
35
|
+
json.user do
|
36
|
+
json.name user.name.to_s
|
37
|
+
json.phone user.phone.to_i
|
38
|
+
json.height user.height.to_f
|
39
|
+
json.email user.email.to_s
|
40
|
+
json.tags user.tags.to_a
|
41
|
+
end
|
42
|
+
```
|
43
|
+
+ 不支持布尔型, 请用整型代替
|
44
|
+
+ 属性必须包含在data对象中,如:{"code":200, "data":{}}
|
45
|
+
### 3. 批量检查
|
46
|
+
+ 支持检查单个项目的所有接口
|
47
|
+
+ 支持仅检查单个接口
|
48
|
+
+ 支持仅检查单个标签下的接口
|
49
|
+
|
50
|
+
## 使用说明
|
51
|
+
|
52
|
+
1. 添加本行在Rails项目的Gemfile中
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
gem 'yapi_check'
|
56
|
+
```
|
57
|
+
|
58
|
+
2. 执行bundle install
|
59
|
+
```shell
|
60
|
+
$ bundle install
|
61
|
+
```
|
62
|
+
|
63
|
+
3. 在项目的Rakefile中间插入如下代码
|
64
|
+
```ruby
|
65
|
+
require 'yapi_check/tasks'
|
66
|
+
ENV['YAPI_PROJECT_TOKEN'] = 'THE_TOKEN_FROM_YOUR_YAPI_PROJECT' # YAPI项目唯一标识(必填), 建议配置在项目里. 该配置可进入YAPI项目查看并拷贝, 功能路径: 设置 -> token配置
|
67
|
+
ENV['YAPI_PROJECT_DOMAIN'] = 'http://YOUR_YAPI_WEBSITE' # YAPI项目域名, 建议配置在个人电脑里, 避免变更 ~/.bashrc or ~/.zshrc
|
68
|
+
ENV['YAPI_API_PREFIX'] = '' # YAPI项目接口前缀, 可设置为'', 不设置默认为/api/v1
|
69
|
+
```
|
70
|
+
|
71
|
+
4. 执行YAPI检查
|
72
|
+
注: 若使用zsh, 请于~/.zshrc中安装rake插件以支持特殊语法 plugins=(... rake)
|
73
|
+
|
74
|
+
```shell
|
75
|
+
# 完整检查
|
76
|
+
$ bundle exec rake yapi:check
|
77
|
+
# or
|
78
|
+
$ rails yapi:check
|
79
|
+
|
80
|
+
# 单个接口检查
|
81
|
+
$ bundle exec rake yapi:check[/healthy_lives/exit_healthy_life]
|
82
|
+
# or
|
83
|
+
$ noglob rails yapi:check[/healthy_lives/exit_healthy_life]
|
84
|
+
# or
|
85
|
+
$ rails 'yapi:check[/healthy_lives/exit_healthy_life]'
|
86
|
+
|
87
|
+
# 单个标签检查
|
88
|
+
$ bundle exec rake yapi:check[,3.3.0]
|
89
|
+
# or
|
90
|
+
$ noglob rails yapi:check[,3.3.0]
|
91
|
+
# or
|
92
|
+
$ rails 'yapi:check[,3.3.0]'
|
93
|
+
```
|
94
|
+
|
95
|
+
## 注意事项
|
96
|
+
本工具仅限Rails项目使用, 请求参数检查强依赖[lucky_param](https://github.com/shootingfly/lucky_param), 响应参数检查强依赖[jbuilder](https://github.com/rails/jbuilder)
|
97
|
+
|
98
|
+
## 贡献
|
99
|
+
|
100
|
+
1. Fork它 ( https://github.com/shootingfly/yapi_check/fork )
|
101
|
+
2. 创建一个新的功能分支 (git checkout -b my-new-feature)
|
102
|
+
3. 进行你的更改
|
103
|
+
4. 运行 `ruby test/yapi_check_test.rb` 来运行测试
|
104
|
+
5. 提交你的更改 (git commit -am 'Add some feature')
|
105
|
+
6. 推送到分支 (git push origin my-new-feature)
|
106
|
+
7. 创建一个新的Pull请求
|
107
|
+
|
108
|
+
## 许可证
|
109
|
+
|
110
|
+
该Gem以[MIT许可证](https://opensource.org/licenses/MIT)的形式提供。
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << 'test'
|
6
|
+
t.libs << 'lib'
|
7
|
+
t.test_files = FileList['test/**/*_test.rb']
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'rubocop/rake_task'
|
11
|
+
|
12
|
+
RuboCop::RakeTask.new
|
13
|
+
|
14
|
+
task default: %i[test rubocop]
|
data/bin/console
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'yapi_check'
|
4
|
+
|
5
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
6
|
+
# with your gem easier. You can also use a different console, if you like.
|
7
|
+
|
8
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
9
|
+
# require 'pry'
|
10
|
+
# Pry.start
|
11
|
+
|
12
|
+
require 'irb'
|
13
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module YapiCheck
|
2
|
+
class Config
|
3
|
+
# YAPI项目令牌
|
4
|
+
def self.yapi_project_token
|
5
|
+
ENV.fetch('YAPI_PROJECT_TOKEN', nil)
|
6
|
+
end
|
7
|
+
|
8
|
+
# YAPI项目开放API访问域名
|
9
|
+
def self.yapi_project_domain
|
10
|
+
ENV.fetch('YAPI_PROJECT_DOMAIN', nil)
|
11
|
+
end
|
12
|
+
|
13
|
+
# 接口统一前缀, 默认为/api/v1
|
14
|
+
def self.yapi_api_prefix
|
15
|
+
ENV.fetch('YAPI_API_PREFIX', '/api/v1')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,241 @@
|
|
1
|
+
module YapiCheck
|
2
|
+
class Executor
|
3
|
+
# 当前支持检查的YAPI请求参数类型
|
4
|
+
YAPI_PARAMS_CLASS = {
|
5
|
+
'string' => :String,
|
6
|
+
'number' => :Float,
|
7
|
+
'integer' => :Integer
|
8
|
+
}.freeze
|
9
|
+
|
10
|
+
# 获取YAPI参数
|
11
|
+
def self.get_yapi_params(detail)
|
12
|
+
yapi_params = []
|
13
|
+
form_params = Array(detail['req_body_form'])
|
14
|
+
form_params.each do |form|
|
15
|
+
s = YapiParams.new
|
16
|
+
s.name = form['name']
|
17
|
+
s.example = form['example']
|
18
|
+
s.desc = form['desc']
|
19
|
+
s.required = form['required'].to_i
|
20
|
+
s.category = 'form'
|
21
|
+
yapi_params << s
|
22
|
+
end
|
23
|
+
query_params = Array(detail['req_query'])
|
24
|
+
query_params.each do |query|
|
25
|
+
s = YapiParams.new
|
26
|
+
s.name = query['name']
|
27
|
+
s.example = query['example']
|
28
|
+
s.desc = query['desc']
|
29
|
+
s.required = query['required'].to_i
|
30
|
+
s.category = 'query'
|
31
|
+
yapi_params << s
|
32
|
+
end
|
33
|
+
exist_key_arr = []
|
34
|
+
begin
|
35
|
+
json_data = JSON.parse(detail['req_body_other'] || '{}')
|
36
|
+
rescue JSON::ParserError => e
|
37
|
+
puts "=== 解析json_data JSON出错#{e.backtrace}"
|
38
|
+
return yapi_params
|
39
|
+
end
|
40
|
+
# 先遍历必填项
|
41
|
+
json_params = json_data['required'] || {}
|
42
|
+
json_params.each do |param_name|
|
43
|
+
s = YapiParams.new
|
44
|
+
s.name = param_name
|
45
|
+
s.required = 1
|
46
|
+
s.type = json_data['properties'][param_name]['type']
|
47
|
+
s.category = 'json'
|
48
|
+
exist_key_arr << param_name
|
49
|
+
yapi_params << s
|
50
|
+
end
|
51
|
+
if json_data['properties'].present?
|
52
|
+
json_data['properties'].each do |k, v|
|
53
|
+
next if exist_key_arr.include?(k)
|
54
|
+
|
55
|
+
s = YapiParams.new
|
56
|
+
s.name = k
|
57
|
+
s.type = v['type']
|
58
|
+
s.category = 'json'
|
59
|
+
s.required = 0
|
60
|
+
yapi_params << s
|
61
|
+
end
|
62
|
+
end
|
63
|
+
yapi_params
|
64
|
+
end
|
65
|
+
|
66
|
+
# 获取响应参数
|
67
|
+
def self.get_response_params(detail)
|
68
|
+
yapi_params = []
|
69
|
+
begin
|
70
|
+
json_params = JSON.parse(detail['res_body'] || '{}')['properties']['data']['properties'] || {}
|
71
|
+
rescue JSON::ParserError => e
|
72
|
+
puts "=== 解析json_params JSON出错#{e.backtrace}"
|
73
|
+
return []
|
74
|
+
end
|
75
|
+
json_params.each do |k, v|
|
76
|
+
s = YapiParams.new
|
77
|
+
s.name = k
|
78
|
+
s.type = v['type']
|
79
|
+
s.category = 'json'
|
80
|
+
yapi_params << s
|
81
|
+
properties = nil
|
82
|
+
case v['type']
|
83
|
+
when 'object'
|
84
|
+
properties = v['properties']
|
85
|
+
when 'array'
|
86
|
+
properties = v['items']['properties']
|
87
|
+
end
|
88
|
+
next unless properties.present?
|
89
|
+
|
90
|
+
properties.each do |sk, sv|
|
91
|
+
s = YapiParams.new
|
92
|
+
s.name = sk
|
93
|
+
s.type = sv['type']
|
94
|
+
s.category = 'json'
|
95
|
+
yapi_params << s
|
96
|
+
end
|
97
|
+
end
|
98
|
+
yapi_params
|
99
|
+
end
|
100
|
+
|
101
|
+
# 获取Rails控制器和动作
|
102
|
+
def self.get_controller_and_action(endpoint, method)
|
103
|
+
request_controller_and_action = Rails.application.routes.recognize_path(endpoint, method: method)
|
104
|
+
controller = "#{request_controller_and_action[:controller]}_controller".classify.constantize
|
105
|
+
action = request_controller_and_action[:action].to_sym
|
106
|
+
[controller, action]
|
107
|
+
rescue ActionController::RoutingError
|
108
|
+
[]
|
109
|
+
end
|
110
|
+
|
111
|
+
# 检查请求参数是否正确(json支持检查类型, query和form不支持)
|
112
|
+
def self.check_request_params(_method, yapi_params, action_source)
|
113
|
+
errors = []
|
114
|
+
yapi_params.each do |yapi_param|
|
115
|
+
# 必填性验证
|
116
|
+
required_check = yapi_param.required == 1 ? "required(:#{yapi_param.name}" : "optional(:#{yapi_param.name}"
|
117
|
+
errors << "#{yapi_param.name}必填性错误,期待#{required_check}" unless action_source.include?(required_check)
|
118
|
+
# 类型验证
|
119
|
+
if yapi_param.category == 'json'
|
120
|
+
type_errors = get_must_not_in_strings(yapi_param).select { |x| action_source.include?(x) }
|
121
|
+
errors << "#{yapi_param.name}类型错误, 期待#{required_check}, #{YAPI_PARAMS_CLASS[yapi_param.type]}}" unless type_errors.empty?
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
errors
|
126
|
+
end
|
127
|
+
|
128
|
+
# 反向匹配参数类型
|
129
|
+
def self.get_must_not_in_strings(yapi_param)
|
130
|
+
name = yapi_param.name
|
131
|
+
case yapi_param.type
|
132
|
+
when 'string' then ["#{name}, :Integer)", "#{name}, :Float)"]
|
133
|
+
when 'number' then ["#{name}, :String)", "#{name}, :Integer)"]
|
134
|
+
when 'integer' then ["#{name}, :String)", "#{name}, :Float)"]
|
135
|
+
else
|
136
|
+
[]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# 检查接口名称是否一致
|
141
|
+
def self.check_request_title(action_title, yapi_title)
|
142
|
+
errors = []
|
143
|
+
errors << action_title unless action_title == yapi_title
|
144
|
+
errors
|
145
|
+
end
|
146
|
+
|
147
|
+
# 核对响应
|
148
|
+
def self.check_response(response_params, jbuilder_source)
|
149
|
+
errors = []
|
150
|
+
response_params.each do |response_param|
|
151
|
+
errors << response_param.name unless jbuilder_source =~ get_response_param_type(response_param.name, response_param.type)
|
152
|
+
end
|
153
|
+
errors
|
154
|
+
end
|
155
|
+
|
156
|
+
# 获取响应参数对应的类型(正则表达式)
|
157
|
+
def self.get_response_param_type(name, type)
|
158
|
+
case type
|
159
|
+
when 'string' then /json\.#{name}\s.*\.to_s/
|
160
|
+
when 'number' then /json\.#{name}\s.*\.to_f/
|
161
|
+
when 'integer' then /json\.#{name}\s.*\.to_i/
|
162
|
+
when 'array' then /json\.#{name}\s(.*\.to_a|.*\sdo)/
|
163
|
+
when 'object' then /json\.#{name}\s(.*\.to_h|do\s)/
|
164
|
+
else
|
165
|
+
raise "Unknown parameter type: #{type}"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# 检查单个接口
|
170
|
+
def self.check_single_interface(interface_id, method_mapping, path_mapping)
|
171
|
+
params = {
|
172
|
+
token: YapiCheck::Config.yapi_project_token,
|
173
|
+
id: interface_id
|
174
|
+
}
|
175
|
+
response = HTTP.get("#{YapiCheck::Config.yapi_project_domain}/api/interface/get", params: params)
|
176
|
+
begin
|
177
|
+
detail = JSON.parse(response.body)['data'].to_h
|
178
|
+
rescue JSON::ParserError => e
|
179
|
+
puts "=== 解析detail JSON出错#{e.backtrace}"
|
180
|
+
return
|
181
|
+
end
|
182
|
+
endpoint = "#{YapiCheck::Config.yapi_api_prefix}#{path_mapping[interface_id]}"
|
183
|
+
controller, action = get_controller_and_action(endpoint, method_mapping[interface_id])
|
184
|
+
unless controller.respond_to?(:instance_method)
|
185
|
+
puts "=== #{endpoint} 接口未实现"
|
186
|
+
return
|
187
|
+
end
|
188
|
+
action_source = controller.instance_method(action).source
|
189
|
+
error = {}
|
190
|
+
response_params = get_response_params(detail)
|
191
|
+
begin
|
192
|
+
if response_params.present?
|
193
|
+
jbuilder_source = expand_jbuilder_with_partial("#{YapiCheck::Config.yapi_api_prefix}#{path_mapping[interface_id]}.json.jbuilder")
|
194
|
+
error[:response_error] = check_response(response_params, jbuilder_source)
|
195
|
+
end
|
196
|
+
rescue StandardError => e
|
197
|
+
puts e
|
198
|
+
puts "=== #{path_mapping[interface_id]} 接口所在目录中缺少的jbuilder文件, 请判断是否需要添加对应jbuilder文件 ==="
|
199
|
+
end
|
200
|
+
yapi_params = get_yapi_params(detail)
|
201
|
+
endpoint_error = {}
|
202
|
+
error[:request_params_error] = check_request_params(method_mapping[interface_id], yapi_params, action_source)
|
203
|
+
endpoint_error["#{method_mapping[interface_id]} #{path_mapping[interface_id]}"] = error if error[:request_params_error].present? || error[:response_error].present?
|
204
|
+
if endpoint_error.present?
|
205
|
+
puts "接口: #{path_mapping[interface_id]} 对应文档中的请求参数或响应参数与当前代码存在不一致,"
|
206
|
+
puts "请求参数不同之处: #{error[:request_params_error]}"
|
207
|
+
puts "响应参数不同之处: #{error[:response_error]}"
|
208
|
+
else
|
209
|
+
puts "=== 请求类型: #{method_mapping[interface_id]}, 接口: #{path_mapping[interface_id]} 检查无误 ==="
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# 使用子视图展开jbuilder(递归)
|
214
|
+
def self.expand_jbuilder_with_partial(jbuilder_file_name, parent_file_name = nil)
|
215
|
+
parent_file_name ||= jbuilder_file_name # 若是相对路径需要知道父级的文件名
|
216
|
+
jbuilder_source = []
|
217
|
+
jbuilder_view_path = File.join('app/views', jbuilder_file_name)
|
218
|
+
File.open(jbuilder_view_path) do |file|
|
219
|
+
file.each_line(chomp: true) do |line|
|
220
|
+
if line =~ %r{json\.partial! '([a-z0-9_/]+)'}
|
221
|
+
partial_file_name = Regexp.last_match(1)
|
222
|
+
partial_file_name_arr = partial_file_name.split('/')
|
223
|
+
if partial_file_name_arr.size == 1
|
224
|
+
# 相对路径 base_measurement => api/v1/measurements/_base_measurement
|
225
|
+
partial_view_name = File.join(File.dirname(parent_file_name), "_#{partial_file_name}")
|
226
|
+
else
|
227
|
+
# 绝对路径 api/v1/measurements/base_measurement => api/v1/measurements/_base_measurement
|
228
|
+
partial_file_name_arr[-1] = "_#{partial_file_name_arr[-1]}"
|
229
|
+
partial_view_name = partial_file_name_arr.join('/')
|
230
|
+
end
|
231
|
+
jbuilder_source << expand_jbuilder_with_partial("#{partial_view_name}.json.jbuilder", parent_file_name)
|
232
|
+
else
|
233
|
+
jbuilder_source << line
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
jbuilder_source.join("\n")
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require_relative '../yapi_check'
|
2
|
+
|
3
|
+
desc 'YAPI检查'
|
4
|
+
namespace :yapi do
|
5
|
+
task :check, %i[uri version] => :environment do |_task, args|
|
6
|
+
raise '请设置YAPI_PROJECT_TOKEN环境变量 ' if YapiCheck::Config.yapi_project_token.nil?
|
7
|
+
raise '请设置YAPI_PROJECT_DOMAIN环境变量 ' if YapiCheck::Config.yapi_project_domain.nil?
|
8
|
+
|
9
|
+
puts "\n=== 开启YAPI接口检查(注意: 接口若使用非json参数, 则无法核对参数类型) ===\n"
|
10
|
+
# 获取接口列表
|
11
|
+
params = {
|
12
|
+
token: YapiCheck::Config.yapi_project_token,
|
13
|
+
page: 1,
|
14
|
+
limit: 1000
|
15
|
+
}
|
16
|
+
response = HTTP.get("#{YapiCheck::Config.yapi_project_domain}/api/interface/list", params: params)
|
17
|
+
interfaces = Array(JSON.parse(response.body).dig('data', 'list'))
|
18
|
+
interface_mapping = {}
|
19
|
+
method_mapping = {}
|
20
|
+
tag_mapping = {}
|
21
|
+
path_mapping = {}
|
22
|
+
interfaces.each do |interface|
|
23
|
+
interface_id = interface['_id']
|
24
|
+
method = interface['method']
|
25
|
+
path = interface['path']
|
26
|
+
tags = interface['tag']
|
27
|
+
method_mapping[interface_id] = method
|
28
|
+
path_mapping[interface_id] = path
|
29
|
+
interface_mapping[path] = interface_id
|
30
|
+
# 根据访问路径check某个API
|
31
|
+
if args[:uri].present?
|
32
|
+
if interface_mapping[args[:uri]].nil?
|
33
|
+
next
|
34
|
+
else
|
35
|
+
YapiCheck::Executor.check_single_interface(interface_mapping[args[:uri]], method_mapping, path_mapping)
|
36
|
+
puts "\n"
|
37
|
+
end
|
38
|
+
|
39
|
+
break
|
40
|
+
end
|
41
|
+
tags.each do |tag|
|
42
|
+
if tag_mapping.key?(tag)
|
43
|
+
tag_mapping[tag] << interface_id
|
44
|
+
else
|
45
|
+
tag_mapping[tag] = [interface_id]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
# 版本号和URI均不传,检查除[接口说明]内容外的所有接口
|
49
|
+
if args[:version].blank? && args[:uri].blank?
|
50
|
+
if interface['title'].start_with?('[接口说明]')
|
51
|
+
next
|
52
|
+
else
|
53
|
+
YapiCheck::Executor.check_single_interface(interface_id, method_mapping, path_mapping)
|
54
|
+
puts "\n"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
# 根据版本check某些API
|
59
|
+
if args[:version].present? && !tag_mapping[args[:version]].nil?
|
60
|
+
interface_ids = tag_mapping[args[:version]]
|
61
|
+
interface_ids.each do |interface_id|
|
62
|
+
YapiCheck::Executor.check_single_interface(interface_id, method_mapping, path_mapping)
|
63
|
+
puts "\n"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/yapi_check.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'method_source'
|
2
|
+
require 'http'
|
3
|
+
|
4
|
+
require_relative 'yapi_check/executor'
|
5
|
+
require_relative 'yapi_check/config'
|
6
|
+
require_relative 'yapi_check/version'
|
7
|
+
require_relative 'yapi_check/yapi_params'
|
8
|
+
|
9
|
+
module YapiCheck
|
10
|
+
class Error < StandardError
|
11
|
+
end
|
12
|
+
end
|
data/sig/yapi_check.rbs
ADDED
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yapi_check
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- KlayHU
|
8
|
+
- Shootingfly
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2024-03-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: http
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '3.0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '3.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: method_source
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '1.0'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '1.0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rails
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '5.2'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '5.2'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: railties
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '4.0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '4.0'
|
84
|
+
description: |2
|
85
|
+
YapiCheck is a gem that automates the process of checking the consistency and conformity between YAPI API documentation and Rails code.
|
86
|
+
It includes features for validating request and response parameters, supporting batch checks, and more.
|
87
|
+
email:
|
88
|
+
- hudongrui_klay@163.com
|
89
|
+
- 790174750@qq.com
|
90
|
+
executables: []
|
91
|
+
extensions: []
|
92
|
+
extra_rdoc_files: []
|
93
|
+
files:
|
94
|
+
- ".rubocop.yml"
|
95
|
+
- CHANGELOG.md
|
96
|
+
- Gemfile
|
97
|
+
- Gemfile.lock
|
98
|
+
- README.md
|
99
|
+
- README.zh-CN.md
|
100
|
+
- Rakefile
|
101
|
+
- bin/console
|
102
|
+
- bin/setup
|
103
|
+
- lib/yapi_check.rb
|
104
|
+
- lib/yapi_check/config.rb
|
105
|
+
- lib/yapi_check/executor.rb
|
106
|
+
- lib/yapi_check/tasks.rb
|
107
|
+
- lib/yapi_check/version.rb
|
108
|
+
- lib/yapi_check/yapi_params.rb
|
109
|
+
- sig/yapi_check.rbs
|
110
|
+
homepage: https://github.com/shootingfly/yapi_check
|
111
|
+
licenses:
|
112
|
+
- MIT
|
113
|
+
metadata:
|
114
|
+
source_code_uri: https://github.com/shootingfly/yapi_check.git
|
115
|
+
rubygems_mfa_required: 'true'
|
116
|
+
post_install_message:
|
117
|
+
rdoc_options: []
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 3.0.0
|
125
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
requirements: []
|
131
|
+
rubygems_version: 3.5.6
|
132
|
+
signing_key:
|
133
|
+
specification_version: 4
|
134
|
+
summary: A tool for checking consistency between YAPI API documentation and Rails
|
135
|
+
code.
|
136
|
+
test_files: []
|