zero-rails_openapi 1.4.2 → 1.4.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|