zero-rails_openapi 1.4.3 → 1.5.1
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/.gitignore +1 -0
- data/.travis.yml +12 -1
- data/CHANGELOG.md +37 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +13 -7
- data/README.md +12 -7
- data/README_zh.md +5 -0
- data/documentation/examples/auto_gen_desc.rb +1 -1
- data/documentation/examples/goods_doc.rb +2 -2
- data/lib/oas_objs/combined_schema.rb +2 -4
- data/lib/oas_objs/example_obj.rb +1 -1
- data/lib/oas_objs/helpers.rb +1 -11
- data/lib/oas_objs/media_type_obj.rb +2 -0
- data/lib/oas_objs/param_obj.rb +2 -2
- data/lib/oas_objs/response_obj.rb +0 -6
- data/lib/oas_objs/schema_obj.rb +41 -51
- data/lib/oas_objs/schema_obj_helpers.rb +33 -36
- data/lib/open_api.rb +4 -4
- data/lib/open_api/config.rb +0 -4
- data/lib/open_api/config_dsl.rb +2 -2
- data/lib/open_api/dsl.rb +6 -9
- data/lib/open_api/dsl/api_info_obj.rb +30 -26
- data/lib/open_api/dsl/components.rb +11 -8
- data/lib/open_api/dsl/helpers.rb +2 -0
- data/lib/open_api/generator.rb +10 -6
- data/lib/open_api/version.rb +1 -1
- data/zero-rails_openapi.gemspec +17 -16
- metadata +17 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8973e94b7dd3112572e08cbf838ed9d5288ae092
|
|
4
|
+
data.tar.gz: a89c1d354004e40c6441c0ede06b848111a5c8bb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 170477a27cca4298664b2d95a7ac65879b79bcbd64ab42f23aaa917b0c45f61506e54c7d5027d9503ae96a04a031f0de34c1dc21cf0ad96ffd5962d98ec9916f
|
|
7
|
+
data.tar.gz: 532e6c8c37abdcd5e7d00c5f10cdedc5ceab6c2e187760a636c1dfda9b4d5b71b9aa5b6ac5d85cfca69c7b8fd3aa21de3a2ff0c2170e790104993a1317320b17
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
sudo: false
|
|
2
2
|
language: ruby
|
|
3
3
|
rvm:
|
|
4
|
-
- 2.4.
|
|
4
|
+
- 2.4.0
|
|
5
5
|
before_install: gem install bundler -v 1.16.0.pre.2
|
|
6
|
+
env:
|
|
7
|
+
global:
|
|
8
|
+
- CC_TEST_REPORTER_ID=fd0a238819079b92c19e99f5f4d6dcc8a5b5b2baf087fceb3723837604b5b0e9
|
|
9
|
+
before_script:
|
|
10
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
|
11
|
+
- chmod +x ./cc-test-reporter
|
|
12
|
+
- ./cc-test-reporter before-build
|
|
13
|
+
script:
|
|
14
|
+
- bundle exec rspec
|
|
15
|
+
after_script:
|
|
16
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# Version Changelog
|
|
2
2
|
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
## [1.5.1 - 100% Test Coverage] - 2017/12/21 - [view diff](https://github.com/zhandao/zero-rails_openapi/compare/v1.4.3...v1.5.0)
|
|
6
|
+
|
|
7
|
+
### Completed the test code (250+ examples), and make it 100% coverage.
|
|
8
|
+
|
|
9
|
+
### Feature
|
|
10
|
+
|
|
11
|
+
1. `type: [String, Integer ..]` will generate an array, which's items
|
|
12
|
+
would be a oneOf combined schema.
|
|
13
|
+
|
|
14
|
+
### Fixed:
|
|
15
|
+
|
|
16
|
+
1. `desc` will override dry's.
|
|
17
|
+
2. `type: something` is passed to `schema_hash`, but not `type`.
|
|
18
|
+
3. Should not `skip` the params inside block.
|
|
19
|
+
4. `body_ref` invalid.
|
|
20
|
+
5. schema `length`'s order is reversed.
|
|
21
|
+
6. Example Obj ref.
|
|
22
|
+
|
|
23
|
+
### Added:
|
|
24
|
+
|
|
25
|
+
1. Use `simplecov`.
|
|
26
|
+
2. CodeClimate test hook.
|
|
27
|
+
3. Test's support.
|
|
28
|
+
4. Designed RSpec matchers `have_keys` and `have_size`.
|
|
29
|
+
5. Designed a set of RSpec's DSL (DSSL) for testing.
|
|
30
|
+
|
|
31
|
+
### Changed:
|
|
32
|
+
|
|
33
|
+
1. WILL NOT do `recognize_is_options_in`.
|
|
34
|
+
2. `instance_eval` => `instance_exec` in dsl.rb.
|
|
35
|
+
3. Guard Clause for `generate_docs` and where schema could be defined.
|
|
36
|
+
4. Change signature of `server` in `api`.
|
|
37
|
+
5. Simplify `recursive`s.
|
|
38
|
+
6. `enum: { 'desc' => :enum1 }` => `enum!: { 'desc' => :enum1 }`
|
|
39
|
+
|
|
3
40
|
## [1.4.2 & 1.4.3] - 2017/12/11&13 - [view diff](https://github.com/zhandao/zero-rails_openapi/compare/v1.4.1...v1.4.3)
|
|
4
41
|
|
|
5
42
|
### Feature
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
zero-rails_openapi (1.
|
|
4
|
+
zero-rails_openapi (1.5.1)
|
|
5
5
|
activesupport (>= 3)
|
|
6
6
|
rails (>= 3)
|
|
7
7
|
|
|
@@ -50,20 +50,20 @@ GEM
|
|
|
50
50
|
concurrent-ruby (1.0.5)
|
|
51
51
|
crass (1.0.3)
|
|
52
52
|
diff-lcs (1.3)
|
|
53
|
+
docile (1.1.5)
|
|
53
54
|
erubi (1.7.0)
|
|
54
55
|
globalid (0.4.1)
|
|
55
56
|
activesupport (>= 4.2.0)
|
|
56
57
|
i18n (0.9.1)
|
|
57
58
|
concurrent-ruby (~> 1.0)
|
|
59
|
+
json (2.1.0)
|
|
58
60
|
loofah (2.1.1)
|
|
59
61
|
crass (~> 1.0.2)
|
|
60
62
|
nokogiri (>= 1.5.9)
|
|
61
|
-
mail (2.
|
|
62
|
-
|
|
63
|
+
mail (2.7.0)
|
|
64
|
+
mini_mime (>= 0.1.1)
|
|
63
65
|
method_source (0.9.0)
|
|
64
|
-
|
|
65
|
-
mime-types-data (~> 3.2015)
|
|
66
|
-
mime-types-data (3.2016.0521)
|
|
66
|
+
mini_mime (1.0.0)
|
|
67
67
|
mini_portile2 (2.3.0)
|
|
68
68
|
minitest (5.10.3)
|
|
69
69
|
nio4r (2.1.0)
|
|
@@ -109,6 +109,11 @@ GEM
|
|
|
109
109
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
110
110
|
rspec-support (~> 3.6.0)
|
|
111
111
|
rspec-support (3.6.0)
|
|
112
|
+
simplecov (0.15.1)
|
|
113
|
+
docile (~> 1.1.0)
|
|
114
|
+
json (>= 1.8, < 3)
|
|
115
|
+
simplecov-html (~> 0.10.0)
|
|
116
|
+
simplecov-html (0.10.2)
|
|
112
117
|
sprockets (3.7.1)
|
|
113
118
|
concurrent-ruby (~> 1.0)
|
|
114
119
|
rack (> 1, < 3)
|
|
@@ -122,7 +127,7 @@ GEM
|
|
|
122
127
|
thread_safe (~> 0.1)
|
|
123
128
|
websocket-driver (0.6.5)
|
|
124
129
|
websocket-extensions (>= 0.1.0)
|
|
125
|
-
websocket-extensions (0.1.
|
|
130
|
+
websocket-extensions (0.1.3)
|
|
126
131
|
|
|
127
132
|
PLATFORMS
|
|
128
133
|
ruby
|
|
@@ -131,6 +136,7 @@ DEPENDENCIES
|
|
|
131
136
|
bundler (~> 1.16.a)
|
|
132
137
|
rake (~> 10.0)
|
|
133
138
|
rspec (~> 3.0)
|
|
139
|
+
simplecov
|
|
134
140
|
zero-rails_openapi!
|
|
135
141
|
|
|
136
142
|
BUNDLED WITH
|
data/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
[](https://badge.fury.io/rb/zero-rails_openapi)
|
|
4
4
|
[](https://travis-ci.org/zhandao/zero-rails_openapi)
|
|
5
5
|
[](https://codeclimate.com/github/zhandao/zero-rails_openapi/maintainability)
|
|
6
|
+
[](https://codeclimate.com/github/zhandao/zero-rails_openapi/test_coverage)
|
|
6
7
|
[](https://gitter.im/zero-rails_openapi/Lobby)
|
|
7
8
|
|
|
8
9
|
Concise DSL for generating OpenAPI Specification 3 (**OAS3**, formerly Swagger3) JSON documentation for Rails application,
|
|
@@ -13,6 +14,9 @@
|
|
|
13
14
|
**Hi, here is ZhanDao = ▽ =
|
|
14
15
|
I think it's a very useful tool when you want to write API document clearly.
|
|
15
16
|
I'm looking forward to your issue and PR, thanks!**
|
|
17
|
+
|
|
18
|
+
And, if you have any questions, please read the test code first.
|
|
19
|
+
such as [api DSL](spec/api_info_obj_spec.rb) and [schema Obj](spec/oas_objs/schema_obj_spec.rb).
|
|
16
20
|
|
|
17
21
|
## Table of Contents
|
|
18
22
|
|
|
@@ -271,7 +275,7 @@
|
|
|
271
275
|
email: 'desc of the parameter :email'
|
|
272
276
|
```
|
|
273
277
|
|
|
274
|
-
You can of course describe the input in it's DSL method (like `query! :done ...`, [this line](https://github.com/zhandao/zero-rails_openapi
|
|
278
|
+
You can of course describe the input in it's DSL method (like `query! :done ...`, [this line](https://github.com/zhandao/zero-rails_openapi#dsl-usage-example)),
|
|
275
279
|
but that will make it long and ugly. We recommend that unite descriptions in this place.
|
|
276
280
|
|
|
277
281
|
In addition, when you want to dry the same parameters (each with a different description), it will be of great use.
|
|
@@ -445,8 +449,8 @@
|
|
|
445
449
|
4. *[IMPORTANT]* Each request bodies you declared will **FUSION** together. <a name="fusion"></a>
|
|
446
450
|
(1) Media-Types will be merged to `requestBody["content"]`
|
|
447
451
|
```ruby
|
|
448
|
-
form
|
|
449
|
-
body :json,
|
|
452
|
+
form data: { }, desc: 'desc'
|
|
453
|
+
body :json, data: { }, desc: 'desc'
|
|
450
454
|
# will generate: "content": { "multipart/form-data": { }, "application/json": { } }
|
|
451
455
|
```
|
|
452
456
|
(2) The same media-types will fusion, but not merge:
|
|
@@ -476,6 +480,7 @@
|
|
|
476
480
|
# method signature
|
|
477
481
|
response(code, desc, media_type = nil, data: { }, type: nil)
|
|
478
482
|
# usage
|
|
483
|
+
resp 200, 'json response', :json, data: { name: 'test' }
|
|
479
484
|
response 200, 'query result', :pdf, type: File
|
|
480
485
|
# same as:
|
|
481
486
|
response 200, 'query result', :pdf, data: File
|
|
@@ -550,9 +555,9 @@
|
|
|
550
555
|
|
|
551
556
|
```ruby
|
|
552
557
|
# method signature
|
|
553
|
-
server(url, desc)
|
|
558
|
+
server(url, desc: '')
|
|
554
559
|
# usage
|
|
555
|
-
server 'http://localhost:3000', 'local'
|
|
560
|
+
server 'http://localhost:3000', desc: 'local'
|
|
556
561
|
```
|
|
557
562
|
|
|
558
563
|
### DSL methods inside [components]()'s block ([code source](lib/open_api/dsl/components.rb))
|
|
@@ -687,7 +692,7 @@
|
|
|
687
692
|
|
|
688
693
|
You can also use Hash to define `enum`:
|
|
689
694
|
```ruby
|
|
690
|
-
query :view, String, desc: 'allows values<br/>', enum
|
|
695
|
+
query :view, String, desc: 'allows values<br/>', enum!: {
|
|
691
696
|
'all goods (default)': :all,
|
|
692
697
|
'only online': :online,
|
|
693
698
|
'only offline': :offline,
|
|
@@ -715,7 +720,7 @@
|
|
|
715
720
|
### Trick6 - Combined Schema (one_of / all_of / any_of / not)
|
|
716
721
|
|
|
717
722
|
```ruby
|
|
718
|
-
query :combination, one_of: [ :GoodSchema, String, { type: Integer, desc: 'integer input'}]
|
|
723
|
+
query :combination, one_of: [ :GoodSchema, String, { type: Integer, desc: 'integer input' } ]
|
|
719
724
|
|
|
720
725
|
form '', data: {
|
|
721
726
|
:combination_in_form => { any_of: [ Integer, String ] }
|
data/README_zh.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
[](https://badge.fury.io/rb/zero-rails_openapi)
|
|
4
4
|
[](https://travis-ci.org/zhandao/zero-rails_openapi)
|
|
5
5
|
[](https://codeclimate.com/github/zhandao/zero-rails_openapi/maintainability)
|
|
6
|
+
[](https://codeclimate.com/github/zhandao/zero-rails_openapi/test_coverage)
|
|
6
7
|
[](https://gitter.im/zero-rails_openapi/Lobby)
|
|
7
8
|
|
|
8
9
|
一套简洁的 DSL,用于为 Rails 应用生成 OpenAPI Specification 3 (**OAS3**, 旧称「Swagger3」) 标准的 JSON 文档。
|
|
@@ -15,6 +16,10 @@
|
|
|
15
16
|
你还可以复用其所[产出](#about-openapidocs-and-openapipaths_index)来写一些扩展,比如参数自动校验什么的(我有写哦)。
|
|
16
17
|
有什么想法敬请 PR,谢过!
|
|
17
18
|
另外,走过路过不妨来个 star?**
|
|
19
|
+
|
|
20
|
+
另外,如果对其行为表现有任何疑惑,敬请先阅读测试代码,这其中已然表明清楚我的大多数考量。
|
|
21
|
+
值得一读的测试:[api DSL](spec/api_info_obj_spec.rb) 以及 [schema Obj](spec/oas_objs/schema_obj_spec.rb)。
|
|
22
|
+
|
|
18
23
|
|
|
19
24
|
## Table of Contents
|
|
20
25
|
|
|
@@ -12,7 +12,7 @@ class V1::GoodsDoc < BaseDoc
|
|
|
12
12
|
|
|
13
13
|
# Instead of:
|
|
14
14
|
# query :view, String, enum: %w[ all online offline expensive cheap ]
|
|
15
|
-
query :view, String, enum
|
|
15
|
+
query :view, String, enum!: {
|
|
16
16
|
'all goods (default)': :all,
|
|
17
17
|
'only online': :online,
|
|
18
18
|
'only offline': :offline,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class V2::GoodsDoc <
|
|
1
|
+
class V2::GoodsDoc < ApiDoc
|
|
2
2
|
SCHEMA_DRY = { a: 1, b: 2 }
|
|
3
3
|
|
|
4
4
|
# skip: [ 'Token' ] do # you can also skip parameters
|
|
@@ -8,7 +8,7 @@ class V2::GoodsDoc < BaseDoc
|
|
|
8
8
|
search_type!: 'search field, allows:<br/>'
|
|
9
9
|
|
|
10
10
|
# Single `query`
|
|
11
|
-
query :view, String, enum
|
|
11
|
+
query :view, String, enum!: {
|
|
12
12
|
'all goods (default)': :all,
|
|
13
13
|
'only online': :online,
|
|
14
14
|
'only offline': :offline,
|
|
@@ -13,16 +13,14 @@ module OpenApi
|
|
|
13
13
|
@schemas = combined_schema.values.first
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def
|
|
16
|
+
def process(options = { inside_desc: false })
|
|
17
17
|
processed[@mode] = @schemas.map do |schema|
|
|
18
18
|
type = schema.is_a?(Hash) ? schema[:type] : schema
|
|
19
19
|
schema = { } unless schema.is_a?(Hash)
|
|
20
|
-
SchemaObj.new(type, schema).
|
|
20
|
+
SchemaObj.new(type, schema).process(options)
|
|
21
21
|
end
|
|
22
22
|
processed
|
|
23
23
|
end
|
|
24
|
-
|
|
25
|
-
alias process process_for
|
|
26
24
|
end
|
|
27
25
|
end
|
|
28
26
|
end
|
data/lib/oas_objs/example_obj.rb
CHANGED
|
@@ -21,7 +21,7 @@ module OpenApi
|
|
|
21
21
|
if keys_of_value.present? && value.is_a?(Array)
|
|
22
22
|
{ value: Hash[keys_of_value.zip(value)] }
|
|
23
23
|
elsif value.is_a?(Symbol) && value['$']
|
|
24
|
-
|
|
24
|
+
RefObj.new(value.to_s.delete('$'), :example).process
|
|
25
25
|
else
|
|
26
26
|
{ value: value }
|
|
27
27
|
end
|
data/lib/oas_objs/helpers.rb
CHANGED
|
@@ -38,20 +38,10 @@ module OpenApi
|
|
|
38
38
|
|
|
39
39
|
def to_processed(who)
|
|
40
40
|
return processed unless truly_present?(@assign)
|
|
41
|
-
|
|
42
|
-
if who.is_a?(Symbol)
|
|
43
|
-
send("#{who}=", @assign)
|
|
44
|
-
else
|
|
45
|
-
processed[who.to_sym] = @assign
|
|
46
|
-
end
|
|
47
|
-
|
|
41
|
+
processed[who.to_sym] = @assign
|
|
48
42
|
processed
|
|
49
43
|
end
|
|
50
44
|
|
|
51
|
-
def to(who)
|
|
52
|
-
self[who.to_sym] = @assign if truly_present?(@assign)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
45
|
def then_merge! # to_processed
|
|
56
46
|
processed.tap { |it| it.merge! @assign if truly_present?(@assign) }
|
|
57
47
|
end
|
|
@@ -29,6 +29,7 @@ module OpenApi
|
|
|
29
29
|
# https://en.wikipedia.org/wiki/Media_type
|
|
30
30
|
# https://zh.wikipedia.org/wiki/%E4%BA%92%E8%81%94%E7%BD%91%E5%AA%92%E4%BD%93%E7%B1%BB%E5%9E%8B
|
|
31
31
|
# https://www.iana.org/assignments/media-types/media-types.xhtml
|
|
32
|
+
# :nocov:
|
|
32
33
|
def media_type_mapping(media_type)
|
|
33
34
|
return media_type if media_type.is_a? String
|
|
34
35
|
case media_type
|
|
@@ -60,6 +61,7 @@ module OpenApi
|
|
|
60
61
|
else nil
|
|
61
62
|
end
|
|
62
63
|
end
|
|
64
|
+
# :nocov:
|
|
63
65
|
end
|
|
64
66
|
end
|
|
65
67
|
end
|
data/lib/oas_objs/param_obj.rb
CHANGED
|
@@ -20,12 +20,12 @@ module OpenApi
|
|
|
20
20
|
|
|
21
21
|
def process
|
|
22
22
|
assign(desc).to_processed 'description'
|
|
23
|
-
processed.tap { |it| it[:schema] = schema.
|
|
23
|
+
processed.tap { |it| it[:schema] = schema.process }
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def desc
|
|
27
27
|
return _desc unless __desc.present?
|
|
28
|
-
schema.preprocess_with_desc __desc
|
|
28
|
+
schema.preprocess_with_desc __desc
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
|
|
@@ -22,12 +22,6 @@ module OpenApi
|
|
|
22
22
|
assign(media_types.map(&:process).reduce({ }, &fusion)).to_processed 'content'
|
|
23
23
|
processed
|
|
24
24
|
end
|
|
25
|
-
|
|
26
|
-
def override(type_hash)
|
|
27
|
-
@hash[:type].merge!(type_hash)
|
|
28
|
-
self.media_type = MediaTypeObj.new(@mt, @hash)
|
|
29
|
-
self
|
|
30
|
-
end
|
|
31
25
|
end
|
|
32
26
|
end
|
|
33
27
|
end
|
data/lib/oas_objs/schema_obj.rb
CHANGED
|
@@ -26,39 +26,34 @@ module OpenApi
|
|
|
26
26
|
merge! schema_hash
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return processed if @preprocessed
|
|
29
|
+
def process(options = { inside_desc: false })
|
|
30
|
+
return processed if preprocessed
|
|
32
31
|
|
|
33
32
|
processed.merge!(processed_type)
|
|
34
33
|
reducx(
|
|
35
34
|
processed_enum_and_length,
|
|
36
35
|
processed_range,
|
|
37
|
-
processed_is_and_format
|
|
36
|
+
processed_is_and_format,
|
|
38
37
|
{
|
|
39
38
|
pattern: _pattern.is_a?(String)? _pattern : _pattern&.inspect&.delete('/'),
|
|
40
|
-
default:
|
|
39
|
+
default: _default,
|
|
41
40
|
examples: self[:examples].present? ? ExampleObj.new(self[:examples], self[:exp_by]).process : nil
|
|
42
41
|
},
|
|
43
|
-
{ as: _as, permit: _permit, not_permit: _npermit, req_if: _req_if, opt_if: _opt_if, blankable: _blank }
|
|
42
|
+
{ as: _as, permit: _permit, not_permit: _npermit, req_if: _req_if, opt_if: _opt_if, blankable: _blank },
|
|
44
43
|
).then_merge!
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
reducx(processed_desc(options)).then_merge!
|
|
44
|
+
reducx(processed_desc(options)).then_merge! # TODO
|
|
48
45
|
end
|
|
49
46
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def preprocess_with_desc desc, param_name = nil
|
|
47
|
+
def preprocess_with_desc desc
|
|
53
48
|
self.__desc = desc
|
|
54
|
-
|
|
49
|
+
process
|
|
55
50
|
self.preprocessed = true
|
|
56
51
|
__desc
|
|
57
52
|
end
|
|
58
53
|
|
|
59
54
|
def processed_desc(options)
|
|
60
|
-
result = __desc ?
|
|
61
|
-
options[:
|
|
55
|
+
result = __desc ? auto_generate_desc : _desc
|
|
56
|
+
options[:inside_desc] ? { description: result } : nil
|
|
62
57
|
end
|
|
63
58
|
|
|
64
59
|
def processed_type(type = self.type)
|
|
@@ -66,16 +61,16 @@ module OpenApi
|
|
|
66
61
|
if t.is_a? Hash
|
|
67
62
|
processed_hash_type(t)
|
|
68
63
|
elsif t.is_a? Array
|
|
69
|
-
|
|
64
|
+
processed_array_type(t)
|
|
70
65
|
elsif t.is_a? Symbol
|
|
71
66
|
RefObj.new(:schema, t).process
|
|
72
|
-
elsif t.in? %w[float double int32 int64]
|
|
73
|
-
{ type: t.match?('int') ? 'integer' : 'number', format: t}
|
|
74
|
-
elsif t.in? %w[binary base64]
|
|
75
|
-
{ type: 'string', format: t}
|
|
76
|
-
elsif t
|
|
67
|
+
elsif t.in? %w[ float double int32 int64 ]
|
|
68
|
+
{ type: t.match?('int') ? 'integer' : 'number', format: t }
|
|
69
|
+
elsif t.in? %w[ binary base64 ]
|
|
70
|
+
{ type: 'string', format: t }
|
|
71
|
+
elsif t == 'file'
|
|
77
72
|
{ type: 'string', format: Config.dft_file_format }
|
|
78
|
-
elsif t
|
|
73
|
+
elsif t == 'datetime'
|
|
79
74
|
{ type: 'string', format: 'date-time' }
|
|
80
75
|
else # other string
|
|
81
76
|
{ type: t }
|
|
@@ -84,32 +79,38 @@ module OpenApi
|
|
|
84
79
|
|
|
85
80
|
def processed_hash_type(t)
|
|
86
81
|
# For supporting this:
|
|
87
|
-
# form 'desc',
|
|
82
|
+
# form 'desc', type: {
|
|
88
83
|
# id!: { type: Integer, enum: 0..5, desc: 'user id' }
|
|
89
|
-
# }
|
|
84
|
+
# }, should have description within schema
|
|
90
85
|
if t.key?(:type)
|
|
91
|
-
SchemaObj.new(t[:type], t).
|
|
92
|
-
|
|
86
|
+
SchemaObj.new(t[:type], t).process(inside_desc: true)
|
|
87
|
+
|
|
88
|
+
# For supporting combined schema in nested schema.
|
|
93
89
|
elsif (t.keys & %i[ one_of any_of all_of not ]).present?
|
|
94
|
-
CombinedSchema.new(t).
|
|
90
|
+
CombinedSchema.new(t).process(inside_desc: true)
|
|
95
91
|
else
|
|
96
|
-
|
|
92
|
+
processed_obj_type(t)
|
|
97
93
|
end
|
|
98
94
|
end
|
|
99
95
|
|
|
100
96
|
def processed_enum_and_length
|
|
101
97
|
process_enum_info
|
|
102
|
-
|
|
98
|
+
process_range_enum_and_lth
|
|
103
99
|
|
|
104
100
|
# generate length range fields by _lth array
|
|
105
|
-
lth = _length || [ ]
|
|
106
|
-
|
|
107
|
-
|
|
101
|
+
if (lth = _length || [ ]).is_a?(Array)
|
|
102
|
+
min, max = [lth.first&.to_i, lth.last&.to_i]
|
|
103
|
+
elsif lth['ge']
|
|
104
|
+
max = lth.to_s.split('_').last.to_i
|
|
105
|
+
elsif lth['le']
|
|
106
|
+
min = lth.to_s.split('_').last.to_i
|
|
107
|
+
end
|
|
108
|
+
|
|
108
109
|
if processed[:type] == 'array'
|
|
109
|
-
{ minItems:
|
|
110
|
+
{ minItems: min, maxItems: max }
|
|
110
111
|
else
|
|
111
|
-
{ minLength:
|
|
112
|
-
end.merge
|
|
112
|
+
{ minLength: min, maxLength: max }
|
|
113
|
+
end.merge(enum: _enum).keep_if &value_present
|
|
113
114
|
end
|
|
114
115
|
|
|
115
116
|
def processed_range
|
|
@@ -122,22 +123,11 @@ module OpenApi
|
|
|
122
123
|
}.keep_if &value_present
|
|
123
124
|
end
|
|
124
125
|
|
|
125
|
-
def processed_is_and_format
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
it[:format] = _format || _is if processed[:format].blank? || _format.present?
|
|
131
|
-
it[:is] = _is
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def recognize_is_options_in(name)
|
|
136
|
-
return unless _is.nil?
|
|
137
|
-
# identify whether `is` patterns matched the name, if so, generate `is`.
|
|
138
|
-
Config.is_options.each do |pattern|
|
|
139
|
-
(self._is = pattern) or break if name.match?(/#{pattern}/)
|
|
140
|
-
end
|
|
126
|
+
def processed_is_and_format
|
|
127
|
+
result = { is: _is }
|
|
128
|
+
# `format` that generated in process_type() may be overwrote here.
|
|
129
|
+
result[:format] = _format || _is if processed[:format].blank? || _format.present?
|
|
130
|
+
result
|
|
141
131
|
end
|
|
142
132
|
|
|
143
133
|
|
|
@@ -3,65 +3,62 @@ module OpenApi
|
|
|
3
3
|
module SchemaObjHelpers
|
|
4
4
|
# TODO: more info and desc configure
|
|
5
5
|
def auto_generate_desc
|
|
6
|
-
if processed[:enum].
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
return __desc if processed[:enum].blank?
|
|
7
|
+
|
|
8
|
+
if @enum_info.present?
|
|
9
|
+
@enum_info.each_with_index do |(info, value), index|
|
|
10
|
+
__desc.concat "<br/>#{index + 1}/ #{info}: #{value}"
|
|
11
|
+
end
|
|
12
|
+
else
|
|
13
|
+
processed[:enum].each_with_index do |value, index|
|
|
14
|
+
__desc.concat "<br/>#{index + 1}/ #{value}"
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
__desc
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def
|
|
21
|
-
|
|
20
|
+
def processed_obj_type(t)
|
|
21
|
+
obj_type = { type: 'object', properties: { }, required: [ ] }
|
|
22
22
|
|
|
23
|
-
_schema = {
|
|
24
|
-
type: 'object',
|
|
25
|
-
properties: { },
|
|
26
|
-
required: [ ]
|
|
27
|
-
}
|
|
28
23
|
t.each do |prop_name, prop_type|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
_schema[:properties]["#{prop_name}".delete('!').to_sym] = recursive_obj_type prop_type
|
|
24
|
+
obj_type[:required] << prop_name.to_s.delete('!') if prop_name['!']
|
|
25
|
+
obj_type[:properties][prop_name.to_s.delete('!').to_sym] = processed_type(prop_type)
|
|
32
26
|
end
|
|
33
|
-
|
|
27
|
+
obj_type.keep_if &value_present
|
|
34
28
|
end
|
|
35
29
|
|
|
36
|
-
def
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
def processed_array_type(t)
|
|
31
|
+
t = t.size == 1 ? t.first : { one_of: t }
|
|
39
32
|
{
|
|
40
33
|
type: 'array',
|
|
41
|
-
|
|
42
|
-
items: recursive_array_type(t.first)
|
|
34
|
+
items: processed_type(t)
|
|
43
35
|
}
|
|
44
36
|
end
|
|
45
37
|
|
|
46
|
-
def
|
|
47
|
-
self[:_enum] = _enum
|
|
48
|
-
self[:_length] = _length
|
|
38
|
+
def process_range_enum_and_lth
|
|
39
|
+
self[:_enum] = str_range_2a(_enum) if _enum.present? && _enum.is_a?(Range)
|
|
40
|
+
self[:_length] = str_range_2a(_length) if _length.present? && _length.is_a?(Range)
|
|
49
41
|
|
|
50
|
-
# generate_enums_by_enum_array
|
|
51
42
|
values = _enum || _value
|
|
52
43
|
self._enum = Array(values) if truly_present?(values)
|
|
53
44
|
end
|
|
54
45
|
|
|
46
|
+
def str_range_2a(val)
|
|
47
|
+
val_class = val.first.class
|
|
48
|
+
action = "to_#{val_class.to_s.downcase[0]}".to_sym
|
|
49
|
+
(val.first.to_s..val.last.to_s).to_a.map(&action)
|
|
50
|
+
end
|
|
51
|
+
|
|
55
52
|
def process_enum_info
|
|
56
53
|
# Support this writing for auto generating desc from enum.
|
|
57
|
-
# enum
|
|
58
|
-
# '
|
|
59
|
-
# '
|
|
54
|
+
# enum!: {
|
|
55
|
+
# 'all_desc': :all,
|
|
56
|
+
# 'one_desc': :one
|
|
60
57
|
# }
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
58
|
+
self._enum ||= self[:enum!]
|
|
59
|
+
return unless self[:enum!].is_a? Hash
|
|
60
|
+
@enum_info = self[:enum!]
|
|
61
|
+
self._enum = self[:enum!].values
|
|
65
62
|
end
|
|
66
63
|
end
|
|
67
64
|
end
|
data/lib/open_api.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
1
|
+
require 'open_api/version'
|
|
2
|
+
require 'open_api/config'
|
|
3
|
+
require 'open_api/generator'
|
|
4
|
+
require 'open_api/dsl'
|
|
5
5
|
|
|
6
6
|
module OpenApi
|
|
7
7
|
include Generator
|
data/lib/open_api/config.rb
CHANGED
data/lib/open_api/config_dsl.rb
CHANGED
|
@@ -10,7 +10,7 @@ module OpenApi
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def info version:, title:, desc: '', **addition
|
|
13
|
-
open_api_docs[@api][:info] = { version: version, title: title, description:
|
|
13
|
+
open_api_docs[@api][:info] = { version: version, title: title, description: desc, **addition }
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def server url, desc: ''
|
|
@@ -30,7 +30,7 @@ module OpenApi
|
|
|
30
30
|
security_scheme scheme_name, { type: 'http', scheme: 'bearer', bearerFormat: format }.merge(other_info)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
def api_key scheme_name, field:, in
|
|
33
|
+
def api_key scheme_name, field:, in: 'header', **other_info
|
|
34
34
|
_in = binding.local_variable_get(:in)
|
|
35
35
|
security_scheme scheme_name, { type: 'apiKey', name: field, in: _in }.merge(other_info)
|
|
36
36
|
end
|
data/lib/open_api/dsl.rb
CHANGED
|
@@ -26,7 +26,7 @@ module OpenApi
|
|
|
26
26
|
def components &block
|
|
27
27
|
apis_tag if @_ctrl_infos.nil?
|
|
28
28
|
current_ctrl = @_ctrl_infos[:components] = Components.new
|
|
29
|
-
current_ctrl.
|
|
29
|
+
current_ctrl.instance_exec(&block)
|
|
30
30
|
current_ctrl.process_objs
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -41,25 +41,22 @@ module OpenApi
|
|
|
41
41
|
.merge! description: '', summary: summary, operationId: action, tags: [@_apis_tag],
|
|
42
42
|
parameters: [ ], requestBody: '', responses: { }, security: [ ], servers: [ ]
|
|
43
43
|
[action, :all].each { |blk_key| @_api_dry_blocks&.[](blk_key)&.each { |blk| api.instance_eval(&blk) } }
|
|
44
|
+
api.param_use = [ ] # `skip` and `use` only affect `api_dry`'s blocks
|
|
45
|
+
api.param_skip = [ ]
|
|
44
46
|
api.param_use = [ ] # `skip` and `use` only affect `api_dry`'s blocks
|
|
45
|
-
api.
|
|
47
|
+
api.instance_exec(&block) if block_given?
|
|
46
48
|
api.process_objs
|
|
47
49
|
api.delete_if { |_, v| v.blank? }
|
|
48
50
|
|
|
49
51
|
path = (@_api_infos ||= { })[routes_info[:path]] ||= { }
|
|
50
|
-
|
|
51
|
-
http_verbs.each { |verb| path[verb] = api }
|
|
52
|
+
(http || routes_info[:http_verb]).split('|').each { |verb| path[verb] = api }
|
|
52
53
|
api
|
|
53
54
|
end
|
|
54
55
|
|
|
55
56
|
# method could be symbol array, like: %i[ .. ]
|
|
56
57
|
def api_dry action = :all, desc = '', &block
|
|
57
58
|
@_api_dry_blocks ||= { }
|
|
58
|
-
|
|
59
|
-
action.each { |m| (@_api_dry_blocks[m.to_sym] ||= [ ]) << block }
|
|
60
|
-
else
|
|
61
|
-
(@_api_dry_blocks[action.to_sym] ||= [ ]) << block
|
|
62
|
-
end
|
|
59
|
+
Array(action).each { |a| (@_api_dry_blocks[a.to_sym] ||= [ ]) << block }
|
|
63
60
|
end
|
|
64
61
|
|
|
65
62
|
def ctrl_routes_list
|
|
@@ -19,9 +19,9 @@ module OpenApi
|
|
|
19
19
|
self[:deprecated] = true
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
alias this_api_is_expired!
|
|
23
|
-
alias this_api_is_unused!
|
|
24
|
-
alias this_api_is_under_repair this_api_is_invalid!
|
|
22
|
+
alias this_api_is_expired! this_api_is_invalid!
|
|
23
|
+
alias this_api_is_unused! this_api_is_invalid!
|
|
24
|
+
alias this_api_is_under_repair! this_api_is_invalid!
|
|
25
25
|
|
|
26
26
|
def desc desc, param_descs = { }
|
|
27
27
|
self.param_descs = param_descs
|
|
@@ -33,14 +33,24 @@ module OpenApi
|
|
|
33
33
|
return if param_use.present? && param_use.exclude?(name)
|
|
34
34
|
|
|
35
35
|
_t = nil
|
|
36
|
-
schema_hash[:desc]
|
|
37
|
-
schema_hash[:desc!]
|
|
36
|
+
schema_hash[:desc] ||= _t if (_t = param_descs[name]).present?
|
|
37
|
+
schema_hash[:desc!] ||= _t if (_t = param_descs["#{name}!".to_sym]).present?
|
|
38
38
|
|
|
39
39
|
param_obj = ParamObj.new(name, param_type, type, required, schema_hash)
|
|
40
40
|
# The definition of the same name parameter will be overwritten
|
|
41
41
|
fill_in_parameters(param_obj)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
# [ header header! path path! query query! cookie cookie! ]
|
|
45
|
+
def _param_agent name, type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash
|
|
46
|
+
combined_schema = one_of || all_of || any_of || (_not = binding.local_variable_get(:not))
|
|
47
|
+
type = schema_hash[:type] ||= type
|
|
48
|
+
pp "[ZRO] Syntax Error: param `#{name}` has no schema type!" and return if type.nil? && combined_schema.nil?
|
|
49
|
+
|
|
50
|
+
schema_hash = CombinedSchema.new(one_of: one_of, all_of: all_of, any_of: any_of, _not: _not) if combined_schema
|
|
51
|
+
param @param_type.to_s.delete('!'), name, type, (@param_type['!'] ? :req : :opt), schema_hash
|
|
52
|
+
end
|
|
53
|
+
|
|
44
54
|
# For supporting this: (just like `form '', data: { }` usage)
|
|
45
55
|
# do_query by: {
|
|
46
56
|
# :search_type => { type: String },
|
|
@@ -49,19 +59,12 @@ module OpenApi
|
|
|
49
59
|
%i[ header header! path path! query query! cookie cookie! ].each do |param_type|
|
|
50
60
|
define_method "do_#{param_type}" do |by:|
|
|
51
61
|
by.each do |key, value|
|
|
52
|
-
|
|
53
|
-
|
|
62
|
+
action = param_type.to_s.delete('!')
|
|
63
|
+
type, value = value.is_a?(Hash) ? [value[:type], value] : [value, { }]
|
|
64
|
+
args = [ key.to_s.delete('!').to_sym, type, value ]
|
|
65
|
+
param_type['!'] || key['!'] ? send("#{action}!", *args) : send(action, *args)
|
|
54
66
|
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def _param_agent name, type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash
|
|
59
|
-
(schema_hash = type) and (type = type.delete(:type)) if type.is_a?(Hash) && type.key?(:type)
|
|
60
|
-
type = schema_hash[:type] if type.nil?
|
|
61
|
-
|
|
62
|
-
combined_schema = one_of || all_of || any_of || (_not = binding.local_variable_get(:not))
|
|
63
|
-
schema_hash = CombinedSchema.new(one_of: one_of, all_of: all_of, any_of: any_of, _not: _not) if combined_schema
|
|
64
|
-
param "#{@param_type}".delete('!'), name, type, (@param_type['!'] ? :req : :opt), schema_hash
|
|
67
|
+
end
|
|
65
68
|
end
|
|
66
69
|
|
|
67
70
|
def param_ref component_key, *keys
|
|
@@ -75,18 +78,13 @@ module OpenApi
|
|
|
75
78
|
self[:requestBody].add_or_fusion(media_type, options.merge(data: data))
|
|
76
79
|
end
|
|
77
80
|
|
|
81
|
+
# [ body body! ]
|
|
78
82
|
def _request_body_agent media_type, data: { }, **options
|
|
79
83
|
request_body (@method_name['!'] ? :req : :opt), media_type, data: data, **options
|
|
80
84
|
end
|
|
81
85
|
|
|
82
86
|
def body_ref component_key
|
|
83
|
-
self[:requestBody] = RefObj.new(:requestBody, component_key)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def response_ref code_compkey_hash
|
|
87
|
-
code_compkey_hash.each do |code, component_key|
|
|
88
|
-
self[:responses][code] = RefObj.new(:response, component_key).process
|
|
89
|
-
end
|
|
87
|
+
self[:requestBody] = RefObj.new(:requestBody, component_key)
|
|
90
88
|
end
|
|
91
89
|
|
|
92
90
|
def form data:, **options
|
|
@@ -110,6 +108,12 @@ module OpenApi
|
|
|
110
108
|
body! media_type, data: data, **options
|
|
111
109
|
end
|
|
112
110
|
|
|
111
|
+
def response_ref code_compkey_hash
|
|
112
|
+
code_compkey_hash.each do |code, component_key|
|
|
113
|
+
self[:responses][code] = RefObj.new(:response, component_key).process
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
113
117
|
def security_require scheme_name, scopes: [ ]
|
|
114
118
|
self[:security] << { scheme_name => scopes }
|
|
115
119
|
end
|
|
@@ -118,12 +122,13 @@ module OpenApi
|
|
|
118
122
|
alias auth security_require
|
|
119
123
|
alias need_auth security_require
|
|
120
124
|
|
|
121
|
-
def server url, desc
|
|
125
|
+
def server url, desc: ''
|
|
122
126
|
self[:servers] << { url: url, description: desc }
|
|
123
127
|
end
|
|
124
128
|
|
|
125
129
|
def order *param_names
|
|
126
130
|
self.param_order = param_names
|
|
131
|
+
# use when api_dry
|
|
127
132
|
self.param_use = param_order if param_use.blank?
|
|
128
133
|
self.param_skip = param_use - param_order
|
|
129
134
|
end
|
|
@@ -136,7 +141,6 @@ module OpenApi
|
|
|
136
141
|
|
|
137
142
|
alias examples param_examples
|
|
138
143
|
|
|
139
|
-
|
|
140
144
|
def process_objs
|
|
141
145
|
self[:parameters]&.each_with_index do |p, index|
|
|
142
146
|
self[:parameters][index] = p.process if p.is_a?(ParamObj)
|
|
@@ -7,13 +7,13 @@ module OpenApi
|
|
|
7
7
|
include DSL::Helpers
|
|
8
8
|
|
|
9
9
|
def schema component_key, type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash
|
|
10
|
-
(schema_hash = type) and (type = type.delete(:type)) if type.is_a?(Hash) && type.key?(:type)
|
|
11
|
-
type ||= schema_hash[:type]
|
|
12
|
-
type ||= load_schema component_key if component_key.try(:superclass) == Config.active_record_base || ApplicationRecord
|
|
13
|
-
|
|
14
10
|
combined_schema = (_not = binding.local_variable_get(:not)) || one_of || all_of || any_of
|
|
11
|
+
schema_hash[:type] ||= type
|
|
12
|
+
schema_hash = load_schema component_key if component_key.try(:superclass) == (Config.active_record_base || ApplicationRecord)
|
|
13
|
+
pp "[ZRO] Syntax Error: component schema `#{component_key}` has no type!" and return if schema_hash[:type].nil? && combined_schema.nil?
|
|
14
|
+
|
|
15
15
|
combined_schema = CombinedSchema.new(one_of: one_of, all_of: all_of, any_of: any_of, _not: _not) if combined_schema
|
|
16
|
-
(self[:schemas] ||= { })[component_key.to_s.to_sym] = combined_schema&.process || SchemaObj.new(
|
|
16
|
+
(self[:schemas] ||= { })[component_key.to_s.to_sym] = combined_schema&.process || SchemaObj.new(schema_hash, { }).process
|
|
17
17
|
end
|
|
18
18
|
arrow_enable :schema
|
|
19
19
|
|
|
@@ -26,9 +26,11 @@ module OpenApi
|
|
|
26
26
|
(self[:parameters] ||= { })[component_key] = ParamObj.new(name, param_type, type, required, schema_hash).process
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
# [ header header! path path! query query! cookie cookie! ]
|
|
29
30
|
def _param_agent component_key, name, type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
combined_schema = one_of || all_of || any_of || (_not = binding.local_variable_get(:not))
|
|
32
|
+
schema_hash[:type] ||= type
|
|
33
|
+
pp "[ZRO] Syntax Error: param `#{name}` has no schema type!" and return if schema_hash[:type].nil? && combined_schema.nil?
|
|
32
34
|
|
|
33
35
|
combined_schema = one_of || all_of || any_of || (_not = binding.local_variable_get(:not))
|
|
34
36
|
schema_hash = CombinedSchema.new(one_of: one_of, all_of: all_of, any_of: any_of, _not: _not) if combined_schema
|
|
@@ -44,6 +46,7 @@ module OpenApi
|
|
|
44
46
|
self[:requestBodies][component_key] = cur.add_or_fusion(media_type, options.merge(data: data))
|
|
45
47
|
end
|
|
46
48
|
|
|
49
|
+
# [ body body! ]
|
|
47
50
|
def _request_body_agent component_key, media_type, data: { }, **options
|
|
48
51
|
request_body component_key,
|
|
49
52
|
(@method_name['!'] ? :req : :opt), media_type, data: data, **options
|
|
@@ -71,7 +74,7 @@ module OpenApi
|
|
|
71
74
|
end
|
|
72
75
|
arrow_enable :bearer_auth
|
|
73
76
|
|
|
74
|
-
def api_key scheme_name, field:, in
|
|
77
|
+
def api_key scheme_name, field:, in: 'header', **other_info
|
|
75
78
|
_in = binding.local_variable_get(:in)
|
|
76
79
|
security_scheme scheme_name, { type: 'apiKey', name: field, in: _in }.merge(other_info)
|
|
77
80
|
end
|
data/lib/open_api/dsl/helpers.rb
CHANGED
|
@@ -5,6 +5,7 @@ module OpenApi
|
|
|
5
5
|
base.extend ClassMethods
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
+
# :nocov:
|
|
8
9
|
def load_schema(model)
|
|
9
10
|
# About `show_attrs`, see:
|
|
10
11
|
# (1) BuilderSupport module: https://github.com/zhandao/zero-rails/blob/master/app/models/concerns/builder_support.rb
|
|
@@ -37,6 +38,7 @@ module OpenApi
|
|
|
37
38
|
end rescue next
|
|
38
39
|
end
|
|
39
40
|
end
|
|
41
|
+
# :nocov:
|
|
40
42
|
|
|
41
43
|
def fill_in_parameters(param_obj)
|
|
42
44
|
name = param_obj.processed[:name]
|
data/lib/open_api/generator.rb
CHANGED
|
@@ -8,17 +8,17 @@ module OpenApi
|
|
|
8
8
|
|
|
9
9
|
module ClassMethods
|
|
10
10
|
def generate_docs(doc_name = nil)
|
|
11
|
+
pp '[ZRO] No documents have been configured!' and return if Config.docs.keys.blank?
|
|
12
|
+
|
|
11
13
|
Dir['./app/controllers/**/*_controller.rb'].each do |file|
|
|
12
14
|
# Do Not `require`!
|
|
13
15
|
# It causes problems, such as making `skip_before_action` not working.
|
|
16
|
+
# :nocov:
|
|
14
17
|
file.sub('./app/controllers/', '').sub('.rb', '').camelize.constantize
|
|
18
|
+
# :nocov:
|
|
15
19
|
end
|
|
16
20
|
Dir[*Array(Config.doc_location)].each { |file| require file }
|
|
17
|
-
|
|
18
|
-
[{ doc_name => generate_doc(doc_name) }]
|
|
19
|
-
else
|
|
20
|
-
Config.docs.keys.map { |api_key| { api_key => generate_doc(api_key) } }.reduce({ }, :merge)
|
|
21
|
-
end
|
|
21
|
+
(doc_name || Config.docs.keys).map { |name| { name => generate_doc(name) } }.reduce({ }, :merge)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def generate_doc(doc_name)
|
|
@@ -42,12 +42,13 @@ module OpenApi
|
|
|
42
42
|
doc[:tags] = doc[:tags].sort { |a, b| a[:name] <=> b[:name] }
|
|
43
43
|
doc[:paths] = doc[:paths].sort.to_h
|
|
44
44
|
|
|
45
|
-
OpenApi.docs[doc_name]
|
|
45
|
+
OpenApi.docs[doc_name] = ActiveSupport::HashWithIndifferentAccess.new(doc.delete_if { |_, v| v.blank? })
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def write_docs(generate_files: true)
|
|
49
49
|
docs = generate_docs
|
|
50
50
|
return unless generate_files
|
|
51
|
+
# :nocov:
|
|
51
52
|
output_path = Config.file_output_path
|
|
52
53
|
FileUtils.mkdir_p output_path
|
|
53
54
|
max_length = docs.keys.map(&:size).sort.last
|
|
@@ -56,6 +57,7 @@ module OpenApi
|
|
|
56
57
|
puts "[ZRO] `#{doc_name.to_s.rjust(max_length)}.json` has been generated."
|
|
57
58
|
File.open("#{output_path}/#{doc_name}.json", 'w') { |file| file.write JSON.pretty_generate doc }
|
|
58
59
|
end
|
|
60
|
+
# :nocov:
|
|
59
61
|
end
|
|
60
62
|
end
|
|
61
63
|
|
|
@@ -64,12 +66,14 @@ module OpenApi
|
|
|
64
66
|
if (f = Config.rails_routes_file)
|
|
65
67
|
File.read(f)
|
|
66
68
|
else
|
|
69
|
+
# :nocov:
|
|
67
70
|
# ref https://github.com/rails/rails/blob/master/railties/lib/rails/tasks/routes.rake
|
|
68
71
|
require './config/routes'
|
|
69
72
|
all_routes = Rails.application.routes.routes
|
|
70
73
|
require 'action_dispatch/routing/inspector'
|
|
71
74
|
inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
|
|
72
75
|
inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, nil)
|
|
76
|
+
# :nocov:
|
|
73
77
|
end
|
|
74
78
|
|
|
75
79
|
@routes_list ||= routes.split("\n").drop(1).map do |line|
|
data/lib/open_api/version.rb
CHANGED
data/zero-rails_openapi.gemspec
CHANGED
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
|
|
2
|
-
lib = File.expand_path(
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require
|
|
4
|
+
require 'open_api/version'
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name =
|
|
7
|
+
spec.name = 'zero-rails_openapi'
|
|
8
8
|
spec.version = OpenApi::VERSION
|
|
9
|
-
spec.authors = [
|
|
10
|
-
spec.email = [
|
|
9
|
+
spec.authors = ['zhandao']
|
|
10
|
+
spec.email = ['x@skippingcat.com']
|
|
11
11
|
|
|
12
|
-
spec.summary =
|
|
13
|
-
spec.description =
|
|
14
|
-
spec.homepage =
|
|
15
|
-
spec.license =
|
|
12
|
+
spec.summary = 'Concise DSL for generating OpenAPI3 documentation.'
|
|
13
|
+
spec.description = 'Concise DSL for generating OpenAPI Specification 3 (OAS3) JSON documentation for Rails application.'
|
|
14
|
+
spec.homepage = 'https://github.com/zhandao/zero-rails_openapi'
|
|
15
|
+
spec.license = 'MIT'
|
|
16
16
|
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
18
18
|
f.match(%r{^(test|spec|features)/})
|
|
19
19
|
end
|
|
20
|
-
spec.bindir =
|
|
20
|
+
spec.bindir = 'exe'
|
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
22
|
-
spec.require_paths = [
|
|
22
|
+
spec.require_paths = ['lib']
|
|
23
23
|
|
|
24
|
-
spec.add_development_dependency
|
|
25
|
-
spec.add_development_dependency
|
|
26
|
-
spec.add_development_dependency
|
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.16.a'
|
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
27
|
+
spec.add_development_dependency 'simplecov'
|
|
27
28
|
|
|
28
|
-
spec.add_runtime_dependency
|
|
29
|
-
spec.add_runtime_dependency
|
|
29
|
+
spec.add_runtime_dependency 'rails', '>= 3'
|
|
30
|
+
spec.add_runtime_dependency 'activesupport', '>= 3'
|
|
30
31
|
|
|
31
32
|
# spec.post_install_message = ""
|
|
32
33
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zero-rails_openapi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- zhandao
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-12-
|
|
11
|
+
date: 2017-12-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -52,6 +52,20 @@ dependencies:
|
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '3.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: simplecov
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
55
69
|
- !ruby/object:Gem::Dependency
|
|
56
70
|
name: rails
|
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -150,7 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
150
164
|
version: '0'
|
|
151
165
|
requirements: []
|
|
152
166
|
rubyforge_project:
|
|
153
|
-
rubygems_version: 2.6.
|
|
167
|
+
rubygems_version: 2.6.12
|
|
154
168
|
signing_key:
|
|
155
169
|
specification_version: 4
|
|
156
170
|
summary: Concise DSL for generating OpenAPI3 documentation.
|