zero-rails_openapi 2.1.5 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/README_zh.md +2 -2
- data/lib/oas_objs/media_type_obj.rb +27 -27
- data/lib/oas_objs/request_body_obj.rb +1 -1
- data/lib/oas_objs/schema_obj.rb +11 -13
- data/lib/open_api/dsl/api.rb +79 -51
- data/lib/open_api/dsl/components.rb +2 -2
- data/lib/open_api/dsl/helpers.rb +8 -14
- data/lib/open_api/version.rb +1 -1
- data/zero-rails_openapi.gemspec +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce57d6f92e37008bf5d5209b19d17cb73929a29c5af1313bb3ebf0ae9c2aeaec
|
4
|
+
data.tar.gz: 2201ddeb5cfabc32ae033b2786b394ebbd82051235c302f092f31eb9255c6a4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55744b89614b4bf82013900a564d4ca698d1ee1acfb7fe4ef13349fae25c97297fb3b62b76e512da9851f45909f4c9501a99eb59711d9cf9e4e282a0bcd12279
|
7
|
+
data.tar.gz: 00c5ec71d60965a0a59f136d016b97f09c01cb2e2decc276acc9132f88db627a055079b4c7c9a5321739387a02b54496ed54cf7fb7277f52f5966891f4a7748c
|
data/README.md
CHANGED
@@ -381,6 +381,7 @@
|
|
381
381
|
body_ref # 2. it links sepcified RefObjs (by component keys) to the body.
|
382
382
|
body, body! # 3. alias of request_body
|
383
383
|
form, form! # 4. to define a multipart/form-data request_body
|
384
|
+
json, json! # 5. to define a application/json request_body
|
384
385
|
data # 5. to define [a] property in the form-data request_body
|
385
386
|
```
|
386
387
|
Bang methods(!) means the specified media-type body is required.
|
@@ -422,6 +423,7 @@
|
|
422
423
|
name!: String,
|
423
424
|
password: { type: String, pattern: /[0-9]{6,10}/ },
|
424
425
|
}
|
426
|
+
json data: { name!: String }
|
425
427
|
|
426
428
|
# Part 5
|
427
429
|
# ** Method Signature
|
data/README_zh.md
CHANGED
@@ -722,9 +722,9 @@
|
|
722
722
|
|
723
723
|
### Trick5 - Auto Generate index/show Actions's Response-Types Based on DB Schema
|
724
724
|
|
725
|
-
Use method `load_schema` in `api_dry
|
725
|
+
~~Use method `load_schema` in `api_dry`.~~
|
726
726
|
|
727
|
-
See this [file](documentation/examples/auto_gen_doc.rb#L51) for uasge information
|
727
|
+
~~See this [file](documentation/examples/auto_gen_doc.rb#L51) for uasge information.~~
|
728
728
|
|
729
729
|
### Trick6 - Combined Schema (one_of / all_of / any_of / not)
|
730
730
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "oas_objs/schema_obj"
|
4
|
+
require "oas_objs/example_obj"
|
5
5
|
|
6
6
|
module OpenApi
|
7
7
|
module DSL
|
@@ -35,30 +35,30 @@ module OpenApi
|
|
35
35
|
def media_type_mapping(media_type)
|
36
36
|
return media_type if media_type.is_a? String
|
37
37
|
case media_type
|
38
|
-
when :app then
|
39
|
-
when :json then
|
40
|
-
when :xml then
|
41
|
-
when :xwww then
|
42
|
-
when :pdf then
|
43
|
-
when :zip then
|
44
|
-
when :gzip then
|
45
|
-
when :doc then
|
46
|
-
when :docx then
|
47
|
-
when :xls then
|
48
|
-
when :xlsx then
|
49
|
-
when :ppt then
|
50
|
-
when :pptx then
|
51
|
-
when :form then
|
52
|
-
when :text then
|
53
|
-
when :plain then
|
54
|
-
when :html then
|
55
|
-
when :csv then
|
56
|
-
when :image then
|
57
|
-
when :png then
|
58
|
-
when :jpeg then
|
59
|
-
when :gif then
|
60
|
-
when :audio then
|
61
|
-
when :video then
|
38
|
+
when :app then "application/*"
|
39
|
+
when :json then "application/json"
|
40
|
+
when :xml then "application/xml"
|
41
|
+
when :xwww then "application/x-www-form-urlencoded"
|
42
|
+
when :pdf then "application/pdf"
|
43
|
+
when :zip then "application/zip"
|
44
|
+
when :gzip then "application/gzip"
|
45
|
+
when :doc then "application/msword"
|
46
|
+
when :docx then "application/application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
47
|
+
when :xls then "application/vnd.ms-excel"
|
48
|
+
when :xlsx then "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
49
|
+
when :ppt then "application/vnd.ms-powerpoint"
|
50
|
+
when :pptx then "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
51
|
+
when :form then "multipart/form-data"; when :form_data then "multipart/form-data"
|
52
|
+
when :text then "text/*"
|
53
|
+
when :plain then "text/plain then charset=utf-8"
|
54
|
+
when :html then "text/html"
|
55
|
+
when :csv then "text/csv"
|
56
|
+
when :image then "image/*"
|
57
|
+
when :png then "image/png"
|
58
|
+
when :jpeg then "image/jpeg"
|
59
|
+
when :gif then "image/gif"
|
60
|
+
when :audio then "audio/*"
|
61
|
+
when :video then "video/*"
|
62
62
|
else nil
|
63
63
|
end
|
64
64
|
end
|
@@ -95,4 +95,4 @@ Media Type Examples
|
|
95
95
|
}
|
96
96
|
}
|
97
97
|
}
|
98
|
-
}
|
98
|
+
}
|
@@ -14,7 +14,7 @@ module OpenApi
|
|
14
14
|
|
15
15
|
def initialize(required, desc)
|
16
16
|
self.media_types = [ ]
|
17
|
-
self.processed = { required: required[
|
17
|
+
self.processed = { required: required.to_s[/req/].present?, description: desc }
|
18
18
|
end
|
19
19
|
|
20
20
|
def absorb(media_type, hash)
|
data/lib/oas_objs/schema_obj.rb
CHANGED
@@ -32,21 +32,19 @@ module OpenApi
|
|
32
32
|
|
33
33
|
def recg_schema_type(t = self.type)
|
34
34
|
t = t.class.in?([Hash, Array, Symbol]) ? t : t.to_s.downcase
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
RefObj.new(:schema, t).process
|
41
|
-
elsif t.in? %w[ float double int32 int64 ]
|
35
|
+
case t
|
36
|
+
when Hash then hash_type(t)
|
37
|
+
when Array then array_type(t)
|
38
|
+
when Symbol then RefObj.new(:schema, t).process
|
39
|
+
when *%w[ float double int32 int64 ]
|
42
40
|
{ type: t['int'] ? 'integer' : 'number', format: t }
|
43
|
-
|
41
|
+
when *%w[ date binary base64 uri ]
|
44
42
|
{ type: 'string', format: t }
|
45
|
-
|
46
|
-
{ type: 'string', format: Config.file_format }
|
47
|
-
elsif t == 'datetime'
|
43
|
+
when 'datetime'
|
48
44
|
{ type: 'string', format: 'date-time' }
|
49
|
-
|
45
|
+
when 'file' # TODO
|
46
|
+
{ type: 'string', format: Config.file_format }
|
47
|
+
when /{=>.*}/
|
50
48
|
self[:values_type] = t[3..-2]
|
51
49
|
{ type: 'object' }
|
52
50
|
else # other string
|
@@ -162,4 +160,4 @@ Simple Model
|
|
162
160
|
"minimum": 0
|
163
161
|
}
|
164
162
|
}
|
165
|
-
}
|
163
|
+
}
|
data/lib/open_api/dsl/api.rb
CHANGED
@@ -7,106 +7,111 @@ module OpenApi
|
|
7
7
|
class Api < Hash
|
8
8
|
include DSL::Helpers
|
9
9
|
|
10
|
+
attr_accessor :_all_params
|
10
11
|
attr_accessor :action_path, :dry_skip, :dry_only, :dry_blocks, :dryed, :param_order
|
11
12
|
|
12
|
-
def initialize(action_path =
|
13
|
+
def initialize(action_path = "", summary: nil, tags: [ ], id: nil)
|
13
14
|
self.action_path = action_path
|
14
15
|
self.dry_blocks = [ ]
|
15
|
-
self.
|
16
|
-
|
16
|
+
self._all_params = { }
|
17
|
+
self.merge!(
|
18
|
+
summary: summary, operationId: id, tags: tags, description: "", parameters: [ ],
|
19
|
+
requestBody: nil, responses: { }, callbacks: { }, links: { }, security: [ ], servers: [ ]
|
20
|
+
)
|
17
21
|
end
|
18
22
|
|
19
23
|
def this_api_is_invalid!(*)
|
20
24
|
self[:deprecated] = true
|
21
25
|
end
|
22
|
-
|
23
26
|
alias this_api_is_expired! this_api_is_invalid!
|
24
27
|
alias this_api_is_unused! this_api_is_invalid!
|
25
28
|
alias this_api_is_under_repair! this_api_is_invalid!
|
26
29
|
|
27
|
-
def desc
|
30
|
+
def desc(desc)
|
28
31
|
self[:description] = desc
|
29
32
|
end
|
30
|
-
|
31
33
|
alias description desc
|
32
34
|
|
33
|
-
def dry
|
35
|
+
def dry(only: nil, skip: nil, none: false)
|
34
36
|
return if dry_blocks.blank? || dryed
|
35
|
-
|
36
|
-
self.
|
37
|
+
|
38
|
+
self.dry_skip = Array(skip).compact.presence
|
39
|
+
self.dry_only = none ? [:none] : Array(only).compact.presence
|
37
40
|
dry_blocks.each { |blk| instance_eval(&blk) }
|
38
41
|
self.dry_skip = self.dry_only = nil
|
39
42
|
self.dryed = true
|
40
43
|
end
|
41
44
|
|
42
|
-
def param
|
45
|
+
def param(param_type, name, type, required, schema = { })
|
43
46
|
return if dry_skip&.include?(name) || dry_only&.exclude?(name)
|
47
|
+
return unless (schema_obj = process_schema_input(type, schema, name))
|
44
48
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
index ? self[:parameters][index] = param_obj : self[:parameters] << param_obj
|
49
|
+
_all_params[name] = schema.is_a?(Hash) ? schema.merge(type:) : { type: } unless param_type["header"]
|
50
|
+
override_or_append_to_parameters(
|
51
|
+
ParamObj.new(name, param_type, type, required, schema_obj)
|
52
|
+
)
|
50
53
|
end
|
51
|
-
|
52
54
|
alias parameter param
|
53
55
|
|
56
|
+
# @!method query(name, type = nil, **schema)
|
57
|
+
# @!method query!(name, type = nil, **schema)
|
58
|
+
# @!method in_query(**params)
|
59
|
+
# @!method in_query!(**params)
|
54
60
|
%i[ header header! path path! query query! cookie cookie! ].each do |param_type|
|
55
|
-
define_method
|
56
|
-
param param_type, name, type, (param_type
|
61
|
+
define_method(param_type) do |name, type = nil, **schema|
|
62
|
+
param param_type, name, type, required?(param_type), schema
|
57
63
|
end
|
58
64
|
|
59
|
-
define_method
|
65
|
+
define_method("in_#{param_type}") do |params|
|
60
66
|
params.each_pair do |param_name, schema|
|
61
|
-
param param_type, param_name, nil, (param_type
|
67
|
+
param param_type, param_name, nil, required?(param_type, param_name), schema
|
62
68
|
end
|
63
69
|
end
|
64
70
|
end
|
65
71
|
|
66
|
-
def param_ref
|
72
|
+
def param_ref(component_key, *keys)
|
67
73
|
self[:parameters] += [component_key, *keys].map { |key| RefObj.new(:parameter, key) }
|
68
74
|
end
|
69
75
|
|
70
76
|
# options: `exp_params` and `examples`
|
71
|
-
def request_body
|
72
|
-
|
77
|
+
def request_body(required, media_type, data: { }, desc: "", **options)
|
78
|
+
self[:requestBody] ||= RequestBodyObj.new(required, desc)
|
79
|
+
self[:requestBody].absorb(media_type, { data:, **options })
|
80
|
+
_all_params.merge!(data)
|
73
81
|
end
|
74
82
|
|
75
|
-
def
|
76
|
-
|
77
|
-
end
|
83
|
+
def body(media_type, data: { }, **) = request_body(:optional, media_type, data:, **)
|
84
|
+
def body!(media_type, data: { }, **) = request_body(:required, media_type, data:, **)
|
78
85
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
def form data:, **options
|
86
|
-
body :form, data: data, **options
|
87
|
-
end
|
86
|
+
def json(data:, **) = body(:json, data:, **)
|
87
|
+
def json!(data:, **) = body!(:json, data:, **)
|
88
|
+
def form(data:, **) = body(:form, data:, **)
|
89
|
+
def form!(data:, **) = body!(:form, data:, **)
|
88
90
|
|
89
|
-
def
|
90
|
-
body! :form, data: data, **options
|
91
|
-
end
|
92
|
-
|
93
|
-
def data name, type = nil, schema = { }
|
91
|
+
def data(name, type = nil, schema = { })
|
94
92
|
schema[:type] = type if type.present?
|
95
93
|
form data: { name => schema }
|
96
94
|
end
|
97
95
|
|
98
|
-
def
|
99
|
-
|
96
|
+
def body_ref(component_key)
|
97
|
+
self[:requestBody] = RefObj.new(:requestBody, component_key)
|
98
|
+
end
|
99
|
+
|
100
|
+
def response(code, desc, media_type = nil, headers: { }, data: { }, **)
|
101
|
+
self[:responses][code.to_s] ||= ResponseObj.new(desc)
|
102
|
+
self[:responses][code.to_s].absorb(desc, media_type, headers:, data:, **)
|
100
103
|
end
|
101
104
|
|
102
105
|
alias_method :resp, :response
|
103
106
|
alias_method :error, :response
|
104
107
|
|
105
|
-
def response_ref
|
106
|
-
code_and_compkey.each
|
108
|
+
def response_ref(code_and_compkey) # = { }
|
109
|
+
code_and_compkey.each do |code, component_key|
|
110
|
+
self[:responses][code.to_s] = RefObj.new(:response, component_key)
|
111
|
+
end
|
107
112
|
end
|
108
113
|
|
109
|
-
def security_require
|
114
|
+
def security_require(scheme_name, scopes: [ ])
|
110
115
|
self[:security] << { scheme_name => scopes }
|
111
116
|
end
|
112
117
|
|
@@ -114,15 +119,17 @@ module OpenApi
|
|
114
119
|
alias auth security_require
|
115
120
|
alias auth_with security_require
|
116
121
|
|
117
|
-
def callback
|
118
|
-
self[:callbacks].deep_merge!
|
122
|
+
def callback(event_name, http_method, callback_url, &block)
|
123
|
+
self[:callbacks].deep_merge!(
|
124
|
+
CallbackObj.new(event_name, http_method, callback_url, &block).process
|
125
|
+
)
|
119
126
|
end
|
120
127
|
|
121
|
-
def server
|
128
|
+
def server(url, desc: "")
|
122
129
|
self[:servers] << { url: url, description: desc }
|
123
130
|
end
|
124
131
|
|
125
|
-
def param_examples
|
132
|
+
def param_examples(exp_params = :all, examples_hash)
|
126
133
|
exp_params = self[:parameters].map(&:name) if exp_params == :all
|
127
134
|
self[:examples] = ExampleObj.new(examples_hash, exp_params, multiple: true).process
|
128
135
|
end
|
@@ -135,10 +142,31 @@ module OpenApi
|
|
135
142
|
|
136
143
|
self[:parameters].map!(&:process)
|
137
144
|
self[:requestBody] = self[:requestBody].try(:process)
|
138
|
-
self[:responses]
|
139
|
-
self[:responses] = self[:responses].sort.to_h
|
145
|
+
self[:responses] = self[:responses].transform_values(&:process).sort.to_h
|
140
146
|
self.delete_if { |_, v| v.blank? }
|
141
147
|
end
|
148
|
+
|
149
|
+
def all_params
|
150
|
+
_all_params.transform_values do |t|
|
151
|
+
if t.is_a?(Hash)
|
152
|
+
t.key?(:type) ? t.merge!(type: t[:type].to_s.underscore) : { type: t }
|
153
|
+
else
|
154
|
+
{ type: t.to_s.underscore }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
def override_or_append_to_parameters(param_obj)
|
162
|
+
# The definition of the same name parameter will be override.
|
163
|
+
index = self[:parameters].map(&:name).index(param_obj.name)
|
164
|
+
index ? self[:parameters][index] = param_obj : self[:parameters] << param_obj
|
165
|
+
end
|
166
|
+
|
167
|
+
def required?(*passed)
|
168
|
+
passed.join["!"] ? :required : :optional
|
169
|
+
end
|
142
170
|
end
|
143
171
|
end
|
144
172
|
end
|
@@ -12,7 +12,7 @@ module OpenApi
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def schema component_key, type = nil, **schema
|
15
|
-
return unless schema = process_schema_input(type, schema, component_key
|
15
|
+
return unless (schema = process_schema_input(type, schema, component_key))
|
16
16
|
self[:schemas][component_key.to_s.to_sym] = schema.process
|
17
17
|
end
|
18
18
|
|
@@ -25,7 +25,7 @@ module OpenApi
|
|
25
25
|
arrow_enable :example
|
26
26
|
|
27
27
|
def param component_key, param_type, name, type, required, schema = { }
|
28
|
-
return unless schema = process_schema_input(type, schema, name)
|
28
|
+
return unless (schema = process_schema_input(type, schema, name))
|
29
29
|
self[:parameters][component_key] = ParamObj.new(name, param_type, type, required, schema).process
|
30
30
|
end
|
31
31
|
|
data/lib/open_api/dsl/helpers.rb
CHANGED
@@ -15,26 +15,20 @@ module OpenApi
|
|
15
15
|
module Helpers
|
16
16
|
extend ActiveSupport::Concern
|
17
17
|
|
18
|
-
def load_schema(model) # TODO: test
|
19
|
-
return unless Config.model_base && model.try(:superclass) == Config.model_base
|
20
|
-
model.columns.map do |column|
|
21
|
-
type = column.sql_type_metadata.type.to_s.camelize
|
22
|
-
type = 'DateTime' if type == 'Datetime'
|
23
|
-
[ column.name.to_sym, Object.const_get(type) ]
|
24
|
-
end.to_h rescue ''
|
25
|
-
end
|
26
|
-
|
27
18
|
def _combined_schema(one_of: nil, all_of: nil, any_of: nil, not: nil, **other)
|
28
19
|
input = (_not = binding.local_variable_get(:not)) || one_of || all_of || any_of
|
29
20
|
CombinedSchema.new(one_of: one_of, all_of: all_of, any_of: any_of, not: _not) if input
|
30
21
|
end
|
31
22
|
|
32
|
-
def process_schema_input(schema_type, schema, name
|
33
|
-
|
23
|
+
def process_schema_input(schema_type, schema, name)
|
24
|
+
if schema.is_a?(Hash)
|
25
|
+
schema[:type] ||= schema_type
|
26
|
+
else
|
27
|
+
schema = { type: schema }
|
28
|
+
end
|
34
29
|
combined_schema = _combined_schema(**schema)
|
35
|
-
|
36
|
-
|
37
|
-
combined_schema || SchemaObj.new(type, load_schema(model) || schema)
|
30
|
+
return Tip.param_no_type(name) if schema[:type].nil? && combined_schema.nil?
|
31
|
+
combined_schema || SchemaObj.new(schema[:type], schema)
|
38
32
|
end
|
39
33
|
|
40
34
|
# Arrow Writing:
|
data/lib/open_api/version.rb
CHANGED
data/zero-rails_openapi.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
22
|
spec.require_paths = ['lib']
|
23
23
|
|
24
|
-
spec.required_ruby_version = '>=
|
24
|
+
spec.required_ruby_version = '>= 3.0.0'
|
25
25
|
|
26
26
|
spec.add_development_dependency 'bundler'
|
27
27
|
spec.add_development_dependency 'rake'
|
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: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zhandao
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-04-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -173,7 +173,7 @@ homepage: https://github.com/zhandao/zero-rails_openapi
|
|
173
173
|
licenses:
|
174
174
|
- MIT
|
175
175
|
metadata: {}
|
176
|
-
post_install_message:
|
176
|
+
post_install_message:
|
177
177
|
rdoc_options: []
|
178
178
|
require_paths:
|
179
179
|
- lib
|
@@ -181,15 +181,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
181
181
|
requirements:
|
182
182
|
- - ">="
|
183
183
|
- !ruby/object:Gem::Version
|
184
|
-
version:
|
184
|
+
version: 3.0.0
|
185
185
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
186
186
|
requirements:
|
187
187
|
- - ">="
|
188
188
|
- !ruby/object:Gem::Version
|
189
189
|
version: '0'
|
190
190
|
requirements: []
|
191
|
-
rubygems_version: 3.
|
192
|
-
signing_key:
|
191
|
+
rubygems_version: 3.5.3
|
192
|
+
signing_key:
|
193
193
|
specification_version: 4
|
194
194
|
summary: Concise DSL for generating OpenAPI3 documentation.
|
195
195
|
test_files: []
|