zero-rails_openapi 2.1.5 → 2.2.0
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/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: []
|