zero-rails_openapi 1.4.2 → 1.4.3
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/CHANGELOG.md +28 -1
- data/Gemfile.lock +1 -1
- data/README.md +62 -45
- data/README_zh.md +4 -4
- data/documentation/examples/auto_gen_doc.rb +1 -1
- data/documentation/examples/examples_controller.rb +7 -11
- data/documentation/examples/goods_doc.rb +1 -1
- data/documentation/parameter.md +2 -1
- data/lib/oas_objs/combined_schema.rb +5 -5
- data/lib/oas_objs/helpers.rb +17 -1
- data/lib/oas_objs/request_body_obj.rb +10 -5
- data/lib/oas_objs/response_obj.rb +10 -8
- data/lib/oas_objs/schema_obj.rb +7 -6
- data/lib/open_api/dsl.rb +2 -2
- data/lib/open_api/dsl/api_info_obj.rb +25 -23
- data/lib/open_api/dsl/common_dsl.rb +5 -15
- data/lib/open_api/dsl/components.rb +12 -5
- data/lib/open_api/dsl/helpers.rb +6 -0
- data/lib/open_api/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fefcfd0fc562daad7532e1dadd0121e8c30c0adb
|
4
|
+
data.tar.gz: 25cf51020674fce5fb428f6b121b6c6a25c02c72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77306d030cba3bfbcb7f6d31eaac31c9ed7dd60355a012166a040633cd6420ebe898b483dcef1fae571da47fcb64871489da7c91069014246dd788e78c2e0815
|
7
|
+
data.tar.gz: 5ad12c05afbf059b177bc1e797e401f49595d7be696e386f89b6e1f945daa511ebc2919c2564b4439e07c0951147682c3ee116efc0f9de4708f845e8e06327b8
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
# Version Changelog
|
2
2
|
|
3
|
+
## [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
|
+
|
5
|
+
### Feature
|
6
|
+
|
7
|
+
1. `example` method in `components` block.
|
8
|
+
2. Request Body (also Response):
|
9
|
+
1. The same media-types will be fusion together.
|
10
|
+
(This means you can write `form` separately.)
|
11
|
+
2. Different media-types will not be replaced, all will be merged in `content`.
|
12
|
+
3. Support flat statement form-data by `data`.
|
13
|
+
|
14
|
+
### Fixed
|
15
|
+
|
16
|
+
1. `generate_doc` raise 'should not nil when merge' if settings[:components] not set.
|
17
|
+
2. `@preprocessed not initialize` warning.
|
18
|
+
|
19
|
+
### Added
|
20
|
+
|
21
|
+
1. Schema option `blankable`.
|
22
|
+
2. Schema option alias `in` to `enum`.
|
23
|
+
3. Schema option `pattern` could be `String` for supporting Time Format.
|
24
|
+
|
25
|
+
### Changed
|
26
|
+
|
27
|
+
1. `form` mandatory requirements pass `data: { }`.
|
28
|
+
2. Remove `request_body`'s parameter `desc` to `**options`.
|
29
|
+
3. Remove aliases of `response`.
|
3
30
|
|
4
31
|
## [1.4.1] - 2017/12/6 - [view diff](https://github.com/zhandao/zero-rails_openapi/compare/v1.4.0...v1.4.1)
|
5
32
|
|
@@ -52,7 +79,7 @@
|
|
52
79
|
2. Support designated http method in `api`.
|
53
80
|
3. The completion of the basic README.
|
54
81
|
|
55
|
-
## [1.3.2 & 1.3.3] - 2017/11/10
|
82
|
+
## [1.3.2 & 1.3.3] - 2017/11/10&21 - [view diff](https://github.com/zhandao/zero-rails_openapi/compare/v1.3.1...v1.3.3)
|
56
83
|
|
57
84
|
### Feature
|
58
85
|
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -22,8 +22,8 @@
|
|
22
22
|
- [Usage - DSL](#usage---dsl)
|
23
23
|
- [DSL methods inside `api` and `api_dry`'s block](#dsl-methods-inside-api-and-api_drys-block)
|
24
24
|
- [DSL methods inside `components`'s block](#dsl-methods-inside-componentss-block-code-source)
|
25
|
-
- [
|
26
|
-
- [
|
25
|
+
- [Run! - Generate JSON documentation file](#run---generate-json-documentation-file)
|
26
|
+
- [Use Swagger UI(very beautiful web page) to show your Documentation](#use-swagger-uivery-beautiful-web-page-to-show-your-documentation)
|
27
27
|
- [Tricks](#tricks)
|
28
28
|
- [Write DSL somewhere else](#trick1---write-the-dsl-somewhere-else)
|
29
29
|
- [Global DRYing](#trick2---global-drying)
|
@@ -370,16 +370,18 @@
|
|
370
370
|
# it links sepcified RefObjs (by component keys) to current body.
|
371
371
|
body, body! # alias of request_body
|
372
372
|
form, form! # define a multipart/form-data body
|
373
|
+
data # define [a] property in the form-data body
|
373
374
|
file, file! # define a File media-type body
|
374
375
|
```
|
375
|
-
|
376
|
+
Bang methods(!) means the specified media-type body is required.
|
377
|
+
|
376
378
|
```ruby
|
377
379
|
# method signature
|
378
|
-
request_body(
|
380
|
+
request_body(required, media_type, data: { }, **options)
|
379
381
|
# usage
|
380
|
-
|
381
|
-
#
|
382
|
-
request_body :opt, :form,
|
382
|
+
# (1) `data` contains all the attributes required by this request body.
|
383
|
+
# (2) `param_name!` means it is required, otherwise without '!' means optional.
|
384
|
+
request_body :opt, :form, data: { id!: Integer, name: { type: String, desc: 'name' } }, desc: 'form-data'
|
383
385
|
|
384
386
|
|
385
387
|
# method signature
|
@@ -389,23 +391,23 @@
|
|
389
391
|
|
390
392
|
|
391
393
|
# method signature
|
392
|
-
body!(media_type,
|
394
|
+
body!(media_type, data: { }, **options)
|
393
395
|
# usage
|
394
396
|
body :json
|
395
397
|
|
396
398
|
|
397
399
|
# method implement
|
398
|
-
def form
|
399
|
-
body :form,
|
400
|
+
def form data:, **options
|
401
|
+
body :form, data: data, **options
|
400
402
|
end
|
401
403
|
# usage
|
402
|
-
form!
|
404
|
+
form! data: {
|
403
405
|
name: String,
|
404
406
|
password: String,
|
405
407
|
password_confirmation: String
|
406
408
|
}
|
407
409
|
# advance usage
|
408
|
-
form
|
410
|
+
form data: {
|
409
411
|
:name! => { type: String, desc: 'user name' },
|
410
412
|
:password! => { type: String, pattern: /[0-9]{6,10}/, desc: 'password' },
|
411
413
|
# optional
|
@@ -414,62 +416,77 @@
|
|
414
416
|
examples: { # ↓ ↓
|
415
417
|
:right_input => [ 'user1', '123456' ],
|
416
418
|
:wrong_input => [ 'user2', 'abc' ]
|
417
|
-
}
|
418
|
-
|
419
|
+
},
|
420
|
+
desc: 'for creating a user'
|
421
|
+
|
422
|
+
|
423
|
+
# method implement
|
424
|
+
def data name, type = nil, schema_hash = { }
|
425
|
+
schema_hash[:type] = type if type.present?
|
426
|
+
form data: { name => schema_hash }
|
427
|
+
end
|
428
|
+
# usage: please look at the 4th point below
|
419
429
|
|
420
430
|
# about `file`
|
421
|
-
def file! media_type,
|
422
|
-
body! media_type,
|
431
|
+
def file! media_type, data: { type: File }, **options
|
432
|
+
body! media_type, data: data, **options
|
423
433
|
end
|
424
434
|
```
|
425
435
|
|
426
|
-
1.
|
427
|
-
|
428
|
-
|
429
|
-
2. `media_type`: we provide some [mapping](lib/oas_objs/media_type_obj.rb) from symbols to real media-types.
|
430
|
-
3. `schema_hash`: as above (see param).
|
431
|
-
**One thing that should be noted is: when use Hash writing, `scham_type` is writed in schema_hash using key :type.**
|
432
|
-
4. `exp_by` and `examples`: for the above example, the following has the same effect:
|
436
|
+
1. `media_type`: we provide some [mapping](lib/oas_objs/media_type_obj.rb) from symbols to real media-types.
|
437
|
+
2. `schema_hash`: as above (see param).
|
438
|
+
3. `exp_by` and `examples`: for the above example, the following has the same effect:
|
433
439
|
```
|
434
440
|
examples: {
|
435
441
|
:right_input => { name: 'user1', password: '123456' },
|
436
442
|
:wrong_input => { name: 'user2', password: 'abc' }
|
437
443
|
}
|
438
444
|
```
|
445
|
+
4. *[IMPORTANT]* Each request bodies you declared will **FUSION** together. <a name="fusion"></a>
|
446
|
+
(1) Media-Types will be merged to `requestBody["content"]`
|
447
|
+
```ruby
|
448
|
+
form 'desc', data: { }
|
449
|
+
body :json, 'desc', data: { }
|
450
|
+
# will generate: "content": { "multipart/form-data": { }, "application/json": { } }
|
451
|
+
```
|
452
|
+
(2) The same media-types will fusion, but not merge:
|
453
|
+
(So that you can write `form` separately, and make `data` method possible.)
|
454
|
+
```ruby
|
455
|
+
data :param_a!, String
|
456
|
+
data :param_b, Integer
|
457
|
+
# or same as:
|
458
|
+
form '', data: { :param_a! => String }
|
459
|
+
form '', data: { :param_b => Integer }
|
460
|
+
# will generate: { "param_a": { "type": "string" }, "param_b": { "type": "integer" } } (call it X)
|
461
|
+
# therefore:
|
462
|
+
# "content": { "multipart/form-data":
|
463
|
+
# { "schema": { "type": "object", "properties": { X }, "required": [ "param_a" ] }
|
464
|
+
# }
|
465
|
+
```
|
439
466
|
|
440
467
|
#### (5) `response` family methods (OAS - [Response Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#response-object))
|
441
468
|
|
442
469
|
Define the responses for the API (action).
|
443
470
|
```
|
444
|
-
response
|
471
|
+
response # aliases: `resp` and `error`
|
445
472
|
response_ref
|
446
|
-
default_response or dft_resp
|
447
|
-
error_response, other_response, oth_resp, error, err_resp # response's aliases, should be used in the error response context.
|
448
|
-
merge_to_resp
|
449
473
|
```
|
450
474
|
|
451
475
|
```ruby
|
452
476
|
# method signature
|
453
|
-
response(
|
477
|
+
response(code, desc, media_type = nil, data: { }, type: nil)
|
454
478
|
# usage
|
455
479
|
response 200, 'query result', :pdf, type: File
|
480
|
+
# same as:
|
481
|
+
response 200, 'query result', :pdf, data: File
|
456
482
|
|
457
483
|
# method signature
|
458
484
|
response_ref(code_compkey_hash)
|
459
485
|
# usage
|
460
486
|
response_ref 700 => :AResp, 800 => :BResp
|
461
|
-
|
462
|
-
# method signature
|
463
|
-
merge_to_resp(code, by:)
|
464
|
-
# usage
|
465
|
-
merge_to_resp 200, by: {
|
466
|
-
data: {
|
467
|
-
type: String
|
468
|
-
}
|
469
|
-
}
|
470
487
|
```
|
471
488
|
|
472
|
-
**practice:**
|
489
|
+
**practice:** Automatically generate responses based on the agreed error class. [AutoGenDoc](documentation/examples/auto_gen_doc.rb#L63)
|
473
490
|
|
474
491
|
#### (6) Authentication and Authorization
|
475
492
|
|
@@ -541,11 +558,11 @@
|
|
541
558
|
### DSL methods inside [components]()'s block ([code source](lib/open_api/dsl/components.rb))
|
542
559
|
|
543
560
|
(Here corresponds to OAS [Components Object](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#componentsObject))
|
544
|
-
|
561
|
+
|
545
562
|
Inside `components`'s block,
|
546
563
|
you can use the same DSL as [[DSL methods inside `api` and `api_dry`'s block]](#dsl-methods-inside-api-and-api_drys-block).
|
547
564
|
But there are two differences:
|
548
|
-
|
565
|
+
|
549
566
|
(1) Each method needs to pass one more parameter `component_key`
|
550
567
|
(in the first parameter position),
|
551
568
|
this will be used as the reference name for the component.
|
@@ -560,9 +577,9 @@
|
|
560
577
|
```ruby
|
561
578
|
query! :UidQuery => [:uid, String]
|
562
579
|
```
|
563
|
-
|
580
|
+
|
564
581
|
(2) You can use `schema` to define a Schema Component.
|
565
|
-
|
582
|
+
|
566
583
|
```ruby
|
567
584
|
# method signature
|
568
585
|
schema(component_key, type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash)
|
@@ -585,8 +602,8 @@
|
|
585
602
|
schema User # easy! And the component_key will be :User
|
586
603
|
```
|
587
604
|
[1] see: [Type](documentation/parameter.md#type-schema_type)
|
588
|
-
|
589
|
-
##
|
605
|
+
|
606
|
+
## Run! - Generate JSON Documentation File
|
590
607
|
|
591
608
|
Use `OpenApi.write_docs`:
|
592
609
|
|
@@ -600,7 +617,7 @@
|
|
600
617
|
|
601
618
|
Then the JSON files will be written to the directories you set. (Each API a file.)
|
602
619
|
|
603
|
-
##
|
620
|
+
## Use Swagger UI(very beautiful web page) to show your Documentation
|
604
621
|
|
605
622
|
Download [Swagger UI](https://github.com/swagger-api/swagger-ui) (version >= 2.3.0 support the OAS3)
|
606
623
|
to your project,
|
data/README_zh.md
CHANGED
@@ -24,8 +24,8 @@
|
|
24
24
|
- [DSL 介绍及用例](#usage---dsl)
|
25
25
|
- [用于 `api` 和 `api_dry` 块内的 DSL(描述 API 的参数、响应等)](#dsl-methods-inside-api-and-api_drys-block)
|
26
26
|
- [用于 `components` 块内的 DSL(描述可复用的组件)](#dsl-methods-inside-componentss-block-code-source)
|
27
|
-
- [执行文档生成](#
|
28
|
-
- [使用 Swagger-UI 可视化所生成的文档](#
|
27
|
+
- [执行文档生成](#run---generate-json-documentation-file)
|
28
|
+
- [使用 Swagger-UI 可视化所生成的文档](#use-swagger-uivery-beautiful-web-page-to-show-your-documentation)
|
29
29
|
- [技巧](#tricks)
|
30
30
|
- [将 DSL 写于他处,与控制器分离](#trick1---write-the-dsl-somewhere-else)
|
31
31
|
- [全局 DRY](#trick2---global-drying)
|
@@ -580,7 +580,7 @@
|
|
580
580
|
```
|
581
581
|
[1] see: [Type](documentation/parameter.md#type-schema_type)
|
582
582
|
|
583
|
-
##
|
583
|
+
## Run! - Generate JSON Documentation File
|
584
584
|
|
585
585
|
Use `OpenApi.write_docs`:
|
586
586
|
|
@@ -594,7 +594,7 @@
|
|
594
594
|
|
595
595
|
Then the JSON files will be written to the directories you set. (Each API a file.)
|
596
596
|
|
597
|
-
##
|
597
|
+
## Use Swagger UI(very beautiful web page) to show your Documentation
|
598
598
|
|
599
599
|
Download [Swagger UI](https://github.com/swagger-api/swagger-ui) (version >= 2.3.0 support the OAS3)
|
600
600
|
to your project,
|
@@ -50,7 +50,7 @@ module AutoGenDoc
|
|
50
50
|
# default_response 'default response', :json
|
51
51
|
model = Object.const_get(action_path.split('#').first.split('/').last[0..-2].camelize) rescue nil
|
52
52
|
type = action.in?(%w[ index show ]) ? Array[load_schema(model)] : String
|
53
|
-
response '200', 'success', :json,
|
53
|
+
response '200', 'success', :json, data: {
|
54
54
|
code: { type: Integer, dft: 200 },
|
55
55
|
msg: { type: String, dft: 'success' },
|
56
56
|
data: { type: type }
|
@@ -30,20 +30,16 @@ class Api::V1::ExamplesController < Api::V1::BaseController
|
|
30
30
|
|
31
31
|
query :test_type, type: String
|
32
32
|
query :combination, one_of: [ :DogSchema, String, { type: Integer, desc: 'integer input'}]
|
33
|
-
form
|
33
|
+
form data: {
|
34
34
|
:combination => { any_of: [ Integer, String ] }
|
35
35
|
}
|
36
36
|
|
37
|
-
response :success, 'success response', :json
|
38
|
-
|
39
|
-
data: {
|
40
|
-
type: [
|
41
|
-
String
|
42
|
-
]
|
43
|
-
}
|
44
|
-
}
|
37
|
+
response :success, 'success response', :json#, data: :Pet
|
38
|
+
security :Token
|
45
39
|
|
46
|
-
|
40
|
+
resp 200, '', :json, data: {
|
41
|
+
a: String
|
42
|
+
}
|
47
43
|
end
|
48
44
|
|
49
45
|
|
@@ -54,7 +50,7 @@ class Api::V1::ExamplesController < Api::V1::BaseController
|
|
54
50
|
|
55
51
|
|
56
52
|
api :create do
|
57
|
-
form
|
53
|
+
form! data: {
|
58
54
|
:name! => String, # <= schema_type is `String`
|
59
55
|
:password! => { type: String, pattern: /[0-9]{6,10}/, desc: 'password' },
|
60
56
|
# optional
|
@@ -28,7 +28,7 @@ class V2::GoodsDoc < BaseDoc
|
|
28
28
|
|
29
29
|
|
30
30
|
api :create, 'POST create a good', use: 'Token' do
|
31
|
-
form!
|
31
|
+
form! data: {
|
32
32
|
:name! => { type: String, desc: 'good\'s name' },
|
33
33
|
:category_id! => { type: Integer, desc: 'sub_category\'s id', npmt: true, range: { ge: 1 }, as: :cate },
|
34
34
|
:price! => { type: Float, desc: 'good\'s price', range: { ge: 0 } },
|
data/documentation/parameter.md
CHANGED
@@ -62,6 +62,7 @@ You can set the schema by following keys (all are optional), the words in parent
|
|
62
62
|
for example the parameter name "user_email" will generate "is: email". Default `is` options are:
|
63
63
|
[email phone password uuid uri url time date], to overwrite it you can set it in initializer `c.is_options = %w[]`.
|
64
64
|
5. If type is Object, for describing each property's schema, the only way is use ref type, like: `{ id: :Id, name: :Name }`
|
65
|
-
- **pattern (regexp, pr, reg)**
|
65
|
+
- **pattern (regexp, pr, reg)**
|
66
|
+
Regexp or Time Format
|
66
67
|
- **default (dft, default_value)**
|
67
68
|
- **as** # TODO
|
@@ -14,12 +14,12 @@ module OpenApi
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def process_for(param_name = nil, options = { desc_inside: false })
|
17
|
-
processed.
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
SchemaObj.new(type, schema).process_for(param_name, options) end
|
17
|
+
processed[@mode] = @schemas.map do |schema|
|
18
|
+
type = schema.is_a?(Hash) ? schema[:type] : schema
|
19
|
+
schema = { } unless schema.is_a?(Hash)
|
20
|
+
SchemaObj.new(type, schema).process_for(param_name, options)
|
22
21
|
end
|
22
|
+
processed
|
23
23
|
end
|
24
24
|
|
25
25
|
alias process process_for
|
data/lib/oas_objs/helpers.rb
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
module OpenApi
|
2
2
|
module Helpers
|
3
|
+
def fusion
|
4
|
+
proc { |a, b| a.merge!(b, &_fusion) }
|
5
|
+
end
|
6
|
+
|
7
|
+
def _fusion
|
8
|
+
proc do |_common_key, x, y|
|
9
|
+
if x.is_a?(Hash) && y.is_a?(Hash)
|
10
|
+
x.merge(y, &_fusion)
|
11
|
+
elsif x.is_a?(Array) && y.is_a?(Array)
|
12
|
+
x.concat(y)
|
13
|
+
else
|
14
|
+
y
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
3
19
|
def truly_present?(obj)
|
4
20
|
obj == false || obj.present?
|
5
21
|
end
|
@@ -14,7 +30,7 @@ module OpenApi
|
|
14
30
|
self
|
15
31
|
end
|
16
32
|
|
17
|
-
#
|
33
|
+
# reducx.then_merge! => for Hash
|
18
34
|
def reducx(*values)
|
19
35
|
@assign = values.compact.reduce({ }, :merge).keep_if &value_present
|
20
36
|
self
|
@@ -8,14 +8,19 @@ module OpenApi
|
|
8
8
|
class RequestBodyObj < Hash
|
9
9
|
include Helpers
|
10
10
|
|
11
|
-
attr_accessor :processed, :
|
12
|
-
def initialize(required,
|
13
|
-
self.
|
14
|
-
self.processed
|
11
|
+
attr_accessor :processed, :media_types
|
12
|
+
def initialize(required, desc)
|
13
|
+
self.media_types = [ ]
|
14
|
+
self.processed = { required: required.match?('req'), description: desc }
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_or_fusion(media_type, hash)
|
18
|
+
media_types << MediaTypeObj.new(media_type, hash)
|
19
|
+
self
|
15
20
|
end
|
16
21
|
|
17
22
|
def process
|
18
|
-
assign(
|
23
|
+
assign(media_types.map(&:process).reduce({ }, &fusion)).to_processed 'content'
|
19
24
|
processed
|
20
25
|
end
|
21
26
|
end
|
@@ -7,17 +7,19 @@ module OpenApi
|
|
7
7
|
class ResponseObj < Hash
|
8
8
|
include Helpers
|
9
9
|
|
10
|
-
attr_accessor :processed, :
|
11
|
-
def initialize(desc
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
10
|
+
attr_accessor :processed, :media_types
|
11
|
+
def initialize(desc)
|
12
|
+
self.media_types = [ ]
|
13
|
+
self.processed = { description: desc }
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_or_fusion(media_type, hash)
|
17
|
+
media_types << MediaTypeObj.new(media_type, hash)
|
18
|
+
self
|
17
19
|
end
|
18
20
|
|
19
21
|
def process
|
20
|
-
assign(
|
22
|
+
assign(media_types.map(&:process).reduce({ }, &fusion)).to_processed 'content'
|
21
23
|
processed
|
22
24
|
end
|
23
25
|
|
data/lib/oas_objs/schema_obj.rb
CHANGED
@@ -30,17 +30,17 @@ module OpenApi
|
|
30
30
|
def process_for(param_name = nil, options = { desc_inside: false })
|
31
31
|
return processed if @preprocessed
|
32
32
|
|
33
|
-
processed.merge!
|
33
|
+
processed.merge!(processed_type)
|
34
34
|
reducx(
|
35
35
|
processed_enum_and_length,
|
36
36
|
processed_range,
|
37
37
|
processed_is_and_format(param_name),
|
38
38
|
{
|
39
|
-
pattern: _pattern&.inspect&.delete('/'),
|
40
|
-
default:
|
39
|
+
pattern: _pattern.is_a?(String)? _pattern : _pattern&.inspect&.delete('/'),
|
40
|
+
default: nil,
|
41
41
|
examples: self[:examples].present? ? ExampleObj.new(self[:examples], self[:exp_by]).process : nil
|
42
42
|
},
|
43
|
-
{ as: _as, permit: _permit, not_permit: _npermit, req_if: _req_if, opt_if: _opt_if }
|
43
|
+
{ as: _as, permit: _permit, not_permit: _npermit, req_if: _req_if, opt_if: _opt_if, blankable: _blank }
|
44
44
|
).then_merge!
|
45
45
|
processed[:default] = _default unless _default.nil?
|
46
46
|
|
@@ -69,7 +69,7 @@ module OpenApi
|
|
69
69
|
recursive_array_type(t)
|
70
70
|
elsif t.is_a? Symbol
|
71
71
|
RefObj.new(:schema, t).process
|
72
|
-
elsif t.in? %w[float double int32 int64]
|
72
|
+
elsif t.in? %w[float double int32 int64]
|
73
73
|
{ type: t.match?('int') ? 'integer' : 'number', format: t}
|
74
74
|
elsif t.in? %w[binary base64]
|
75
75
|
{ type: 'string', format: t}
|
@@ -142,7 +142,7 @@ module OpenApi
|
|
142
142
|
|
143
143
|
|
144
144
|
{ # SELF_MAPPING
|
145
|
-
_enum: %i[ enum
|
145
|
+
_enum: %i[ enum in values allowable_values ],
|
146
146
|
_value: %i[ must_be value allowable_value ],
|
147
147
|
_range: %i[ range number_range ],
|
148
148
|
_length: %i[ length lth size ],
|
@@ -157,6 +157,7 @@ module OpenApi
|
|
157
157
|
_npermit: %i[ npmt not_permit unpermit ], # NOT OAS Spec, it's for zero-params_processor
|
158
158
|
_req_if: %i[ req_if req_when ], # NOT OAS Spec, it's for zero-params_processor
|
159
159
|
_opt_if: %i[ opt_if opt_when ], # NOT OAS Spec, it's for zero-params_processor
|
160
|
+
_blank: %i[ blank blankable ], # NOT OAS Spec, it's for zero-params_processor
|
160
161
|
}.each do |key, aliases|
|
161
162
|
define_method key do
|
162
163
|
return self[key] unless self[key].nil?
|
data/lib/open_api/dsl.rb
CHANGED
@@ -27,7 +27,7 @@ module OpenApi
|
|
27
27
|
apis_tag if @_ctrl_infos.nil?
|
28
28
|
current_ctrl = @_ctrl_infos[:components] = Components.new
|
29
29
|
current_ctrl.instance_eval(&block)
|
30
|
-
current_ctrl.
|
30
|
+
current_ctrl.process_objs
|
31
31
|
end
|
32
32
|
|
33
33
|
def api action, summary = '', http: nil, skip: [ ], use: [ ], &block
|
@@ -43,7 +43,7 @@ module OpenApi
|
|
43
43
|
[action, :all].each { |blk_key| @_api_dry_blocks&.[](blk_key)&.each { |blk| api.instance_eval(&blk) } }
|
44
44
|
api.param_use = [ ] # `skip` and `use` only affect `api_dry`'s blocks
|
45
45
|
api.instance_eval(&block) if block_given?
|
46
|
-
api.
|
46
|
+
api.process_objs
|
47
47
|
api.delete_if { |_, v| v.blank? }
|
48
48
|
|
49
49
|
path = (@_api_infos ||= { })[routes_info[:path]] ||= { }
|
@@ -38,8 +38,7 @@ module OpenApi
|
|
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
|
-
|
42
|
-
index.present? ? self[:parameters][index] = param_obj : self[:parameters] << param_obj
|
41
|
+
fill_in_parameters(param_obj)
|
43
42
|
end
|
44
43
|
|
45
44
|
# For supporting this: (just like `form '', data: { }` usage)
|
@@ -69,45 +68,46 @@ module OpenApi
|
|
69
68
|
self[:parameters].concat([component_key].concat(keys).map { |key| RefObj.new(:parameter, key).process })
|
70
69
|
end
|
71
70
|
|
72
|
-
|
73
|
-
|
71
|
+
# options: `exp_by` and `examples`
|
72
|
+
def request_body required, media_type, data: { }, **options
|
73
|
+
desc = options.delete(:desc) || ''
|
74
|
+
self[:requestBody] = RequestBodyObj.new(required, desc) unless self[:requestBody].is_a?(RequestBodyObj)
|
75
|
+
self[:requestBody].add_or_fusion(media_type, options.merge(data: data))
|
74
76
|
end
|
75
77
|
|
76
|
-
def _request_body_agent media_type,
|
77
|
-
request_body (@method_name['!'] ? :req : :opt), media_type,
|
78
|
+
def _request_body_agent media_type, data: { }, **options
|
79
|
+
request_body (@method_name['!'] ? :req : :opt), media_type, data: data, **options
|
78
80
|
end
|
79
81
|
|
80
82
|
def body_ref component_key
|
81
83
|
self[:requestBody] = RefObj.new(:requestBody, component_key).process
|
82
84
|
end
|
83
85
|
|
84
|
-
def merge_to_resp code, by:
|
85
|
-
_response = self[:responses].fetch(code)
|
86
|
-
self[:responses][code] = _response.override(by).process
|
87
|
-
end
|
88
|
-
|
89
86
|
def response_ref code_compkey_hash
|
90
87
|
code_compkey_hash.each do |code, component_key|
|
91
88
|
self[:responses][code] = RefObj.new(:response, component_key).process
|
92
89
|
end
|
93
90
|
end
|
94
91
|
|
95
|
-
|
96
|
-
|
97
|
-
body :form, desc, hash
|
92
|
+
def form data:, **options
|
93
|
+
body :form, data: data, **options
|
98
94
|
end
|
99
95
|
|
100
|
-
def form!
|
101
|
-
body! :form,
|
96
|
+
def form! data:, **options
|
97
|
+
body! :form, data: data, **options
|
102
98
|
end
|
103
99
|
|
104
|
-
|
105
|
-
|
106
|
-
|
100
|
+
def data name, type = nil, schema_hash = { }
|
101
|
+
schema_hash[:type] = type if type.present?
|
102
|
+
form data: { name => schema_hash }
|
107
103
|
end
|
108
104
|
|
109
|
-
def file
|
110
|
-
body
|
105
|
+
def file media_type, data: { type: File }, **options
|
106
|
+
body media_type, data: data, **options
|
107
|
+
end
|
108
|
+
|
109
|
+
def file! media_type, data: { type: File }, **options
|
110
|
+
body! media_type, data: data, **options
|
111
111
|
end
|
112
112
|
|
113
113
|
def security_require scheme_name, scopes: [ ]
|
@@ -129,7 +129,7 @@ module OpenApi
|
|
129
129
|
end
|
130
130
|
|
131
131
|
def param_examples exp_by = :all, examples_hash
|
132
|
-
|
132
|
+
process_objs
|
133
133
|
exp_by = self[:parameters].map { |p| p[:name] } if exp_by == :all
|
134
134
|
self[:examples] = ExampleObj.new(examples_hash, exp_by).process
|
135
135
|
end
|
@@ -137,7 +137,7 @@ module OpenApi
|
|
137
137
|
alias examples param_examples
|
138
138
|
|
139
139
|
|
140
|
-
def
|
140
|
+
def process_objs
|
141
141
|
self[:parameters]&.each_with_index do |p, index|
|
142
142
|
self[:parameters][index] = p.process if p.is_a?(ParamObj)
|
143
143
|
end
|
@@ -147,6 +147,8 @@ module OpenApi
|
|
147
147
|
self[:parameters][param_order.index(p[:name]) || -1] = p
|
148
148
|
end if param_order.present?
|
149
149
|
|
150
|
+
self[:requestBody] = self[:requestBody].try :process
|
151
|
+
|
150
152
|
self[:responses]&.each do |code, obj|
|
151
153
|
self[:responses][code] = obj.process if obj.is_a?(ResponseObj)
|
152
154
|
end
|
@@ -25,23 +25,13 @@ module OpenApi
|
|
25
25
|
end
|
26
26
|
|
27
27
|
# `code`: when defining components, `code` means `component_key`
|
28
|
-
def response code, desc, media_type = nil,
|
29
|
-
|
28
|
+
def response code, desc, media_type = nil, data: { }, type: nil
|
29
|
+
self[:responses][code] = ResponseObj.new(desc) unless (self[:responses] ||= { })[code].is_a?(ResponseObj)
|
30
|
+
self[:responses][code].add_or_fusion(media_type, { data: type || data })
|
30
31
|
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
{ # alias_methods mapping
|
37
|
-
response: %i[ error_response resp ],
|
38
|
-
default_response: %i[ dft_resp dft_response ],
|
39
|
-
error_response: %i[ other_response oth_resp error err_resp ],
|
40
|
-
}.each do |original_name, aliases|
|
41
|
-
aliases.each do |alias_name|
|
42
|
-
alias_method alias_name, original_name
|
43
|
-
end
|
44
|
-
end
|
33
|
+
alias_method :resp, :response
|
34
|
+
alias_method :error, :response
|
45
35
|
end
|
46
36
|
end
|
47
37
|
end
|
@@ -37,13 +37,16 @@ module OpenApi
|
|
37
37
|
end
|
38
38
|
arrow_enable :_param_agent
|
39
39
|
|
40
|
-
def request_body component_key, required, media_type,
|
41
|
-
|
40
|
+
def request_body component_key, required, media_type, data: { }, **options
|
41
|
+
desc = options.delete(:desc) || ''
|
42
|
+
cur = (self[:requestBodies] ||= { })[component_key]
|
43
|
+
cur = RequestBodyObj.new(required, desc) unless cur.is_a?(RequestBodyObj)
|
44
|
+
self[:requestBodies][component_key] = cur.add_or_fusion(media_type, options.merge(data: data))
|
42
45
|
end
|
43
46
|
|
44
|
-
def _request_body_agent component_key, media_type,
|
47
|
+
def _request_body_agent component_key, media_type, data: { }, **options
|
45
48
|
request_body component_key,
|
46
|
-
(@method_name['!'] ? :req : :opt), media_type,
|
49
|
+
(@method_name['!'] ? :req : :opt), media_type, data: data, **options
|
47
50
|
end
|
48
51
|
arrow_enable :_request_body_agent
|
49
52
|
|
@@ -74,7 +77,11 @@ module OpenApi
|
|
74
77
|
end
|
75
78
|
arrow_enable :api_key
|
76
79
|
|
77
|
-
def
|
80
|
+
def process_objs
|
81
|
+
self[:requestBodies]&.each do |key, obj|
|
82
|
+
self[:requestBodies][key] = obj.process
|
83
|
+
end
|
84
|
+
|
78
85
|
self[:responses]&.each do |code, obj|
|
79
86
|
self[:responses][code] = obj.process if obj.is_a?(ResponseObj)
|
80
87
|
end
|
data/lib/open_api/dsl/helpers.rb
CHANGED
@@ -38,6 +38,12 @@ module OpenApi
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
def fill_in_parameters(param_obj)
|
42
|
+
name = param_obj.processed[:name]
|
43
|
+
index = self[:parameters].map { |p| p.processed[:name] if p.is_a?(ParamObj) }.index(name)
|
44
|
+
index.present? ? self[:parameters][index] = param_obj : self[:parameters] << param_obj
|
45
|
+
end
|
46
|
+
|
41
47
|
# Arrow Writing:
|
42
48
|
# response :RespComponent => [ '200', 'success', :json ]
|
43
49
|
# It is equivalent to:
|
data/lib/open_api/version.rb
CHANGED
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.
|
4
|
+
version: 1.4.3
|
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-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|