zero-rails_openapi 1.5.2 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -54,7 +54,7 @@ class Api::V1::ExamplesController < Api::V1::BaseController
54
54
  :name! => String, # <= schema_type is `String`
55
55
  :password! => { type: String, pattern: /[0-9]{6,10}/, desc: 'password' },
56
56
  # optional
57
- :remarks => { type: String, desc: 'remarks' }, # <= schema_type is `String`, and schema_hash is { desc: '..' }
57
+ :remarks => { type: String, desc: 'remarks' }, # <= schema_type is `String`, and schema_info is { desc: '..' }
58
58
  }
59
59
  end
60
60
  end
@@ -1,4 +1,4 @@
1
- ### More Explanation for `param` and `schema_hash`
1
+ ### More Explanation for `param` and `schema_info`
2
2
 
3
3
  #### param_type (param_location)
4
4
  OpenAPI 3.0 distinguishes between the following parameter types based on the parameter location:
@@ -15,7 +15,7 @@ Parameter's (schema) type. We call it `schema_type` because it is inside SchemaO
15
15
 
16
16
  Support all [data types](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#dataTypes) defined in OAS.
17
17
 
18
- In addition, you can use `format` in schema_hash to define in fine detail the data type being used, like:
18
+ In addition, you can use `format` in schema_info to define in fine detail the data type being used, like:
19
19
  int32, float, date ...
20
20
  All the types you can use as following:
21
21
  - **String, 'binary', 'base64'**
@@ -41,7 +41,7 @@ All the types you can use as following:
41
41
  #### Schema Hash
42
42
 
43
43
  The [[schema]](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.0.md#schemaObject) defining the type used for the parameter.
44
- schema_hash(optional) will be used to generate Schema Object inside Parameter Object.
44
+ schema_info(optional) will be used to generate Schema Object inside Parameter Object.
45
45
  [source code](https://github.com/zhandao/zero-rails_openapi/blob/master/lib/oas_objs/schema_obj.rb)
46
46
  You can set the schema by following keys (all are optional), the words in parentheses are available aliases of the keys:
47
47
  - **enum (values, allowable_values)**
@@ -19,29 +19,18 @@ module OpenApi
19
19
  end
20
20
 
21
21
  def process
22
- assign(desc).to_processed 'description'
23
- processed.tap { |it| it[:schema] = schema.process }
22
+ assign(desc).to_processed :description
23
+ assign(schema.process).to_processed :schema
24
+ processed
24
25
  end
25
26
 
26
27
  def desc
27
- return _desc unless __desc.present?
28
- schema.preprocess_with_desc __desc
28
+ return self[:desc] || self[:description] if (self[:desc!] || self[:description!]).blank?
29
+ schema.__desc # not a copy of __desc, means desc() will change if schema.__desc changes.
29
30
  end
30
31
 
31
-
32
- # Getters and Setters of the original values that was passed to param()
33
- # This mapping allows user to select the aliases in DSL writing,
34
- # without increasing the complexity of the implementation.
35
- { # SELF_MAPPING
36
- _range: %i[ range number_range ],
37
- _length: %i[ length lth ],
38
- _desc: %i[ desc description ],
39
- __desc: %i[ desc! description! ],
40
- }.each do |key, aliases|
41
- define_method key do
42
- aliases.each { |alias_name| self[key] ||= self[alias_name] } if self[key].nil?
43
- self[key]
44
- end
32
+ def name
33
+ processed[:name]
45
34
  end
46
35
  end
47
36
  end
@@ -13,7 +13,8 @@ module OpenApi
13
13
  }
14
14
  end
15
15
 
16
- def process; processed; end
16
+ def process; processed end
17
+ def name; nil end
17
18
  end
18
19
  end
19
20
  end
@@ -13,55 +13,30 @@ module OpenApi
13
13
 
14
14
  attr_accessor :processed, :type, :preprocessed
15
15
 
16
- def initialize(type, schema_hash)
16
+ def initialize(type, schema_info)
17
17
  self.preprocessed = false
18
18
  self.processed = { }
19
- # [Note] Here is no limit to type, even if the input isn't up to OAS,
20
- # like: double, float, hash.
21
- # My consideration is, OAS can't express some cases like:
22
- # `total_price` should be double, is_a `price`, and match /^.*\..*$/
23
- # However, user can decide how to write --
24
- # `type: number, format: double`, or `type: double`
25
19
  self.type = type
26
- merge! schema_hash
20
+ merge! schema_info
27
21
  end
28
22
 
29
23
  def process(options = { inside_desc: false })
30
- return processed if preprocessed
31
-
32
24
  processed.merge!(processed_type)
33
- reducx(
34
- processed_enum_and_length,
35
- processed_range,
36
- processed_is_and_format,
37
- {
38
- pattern: _pattern.is_a?(String)? _pattern : _pattern&.inspect&.delete('/'),
39
- default: _default,
40
- examples: self[:examples].present? ? ExampleObj.new(self[:examples], self[:exp_by]).process : nil
41
- },
42
- { as: _as, permit: _permit, not_permit: _npermit, req_if: _req_if, opt_if: _opt_if, blankable: _blank },
43
- ).then_merge!
44
- reducx(processed_desc(options)).then_merge! # TODO
45
- end
46
-
47
- def preprocess_with_desc desc
48
- self.__desc = desc
49
- process
50
- self.preprocessed = true
51
- __desc
25
+ reducx(enum_and_length, range, is_and_format, pattern_default_and_other, desc(options)).then_merge!
52
26
  end
53
27
 
54
- def processed_desc(options)
28
+ def desc(inside_desc:)
55
29
  result = __desc ? auto_generate_desc : _desc
56
- options[:inside_desc] ? { description: result } : nil
30
+ return unless inside_desc
31
+ { description: result }
57
32
  end
58
33
 
59
34
  def processed_type(type = self.type)
60
35
  t = type.class.in?([Hash, Array, Symbol]) ? type : type.to_s.downcase
61
36
  if t.is_a? Hash
62
- processed_hash_type(t)
37
+ hash_type(t)
63
38
  elsif t.is_a? Array
64
- processed_array_type(t)
39
+ array_type(t)
65
40
  elsif t.is_a? Symbol
66
41
  RefObj.new(:schema, t).process
67
42
  elsif t.in? %w[ float double int32 int64 ]
@@ -77,33 +52,17 @@ module OpenApi
77
52
  end
78
53
  end
79
54
 
80
- def processed_hash_type(t)
81
- # For supporting this:
82
- # form 'desc', type: {
83
- # id!: { type: Integer, enum: 0..5, desc: 'user id' }
84
- # }, should have description within schema
85
- if t.key?(:type)
86
- SchemaObj.new(t[:type], t).process(inside_desc: true)
87
-
88
- # For supporting combined schema in nested schema.
89
- elsif (t.keys & %i[ one_of any_of all_of not ]).present?
90
- CombinedSchema.new(t).process(inside_desc: true)
91
- else
92
- processed_obj_type(t)
93
- end
94
- end
95
-
96
- def processed_enum_and_length
55
+ def enum_and_length
97
56
  process_enum_info
98
57
  process_range_enum_and_lth
99
58
 
100
59
  # generate length range fields by _lth array
101
- if (lth = _length || [ ]).is_a?(Array)
60
+ if (lth = _length || '').is_a?(Array)
102
61
  min, max = [lth.first&.to_i, lth.last&.to_i]
103
62
  elsif lth['ge']
104
- max = lth.to_s.split('_').last.to_i
105
- elsif lth['le']
106
63
  min = lth.to_s.split('_').last.to_i
64
+ elsif lth['le']
65
+ max = lth.to_s.split('_').last.to_i
107
66
  end
108
67
 
109
68
  if processed[:type] == 'array'
@@ -113,23 +72,32 @@ module OpenApi
113
72
  end.merge!(enum: _enum).keep_if &value_present
114
73
  end
115
74
 
116
- def processed_range
75
+ def range
117
76
  range = _range || { }
118
77
  {
119
- minimum: range[:gt] || range[:ge],
78
+ minimum: range[:gt] || range[:ge],
120
79
  exclusiveMinimum: range[:gt].present? ? true : nil,
121
- maximum: range[:lt] || range[:le],
80
+ maximum: range[:lt] || range[:le],
122
81
  exclusiveMaximum: range[:lt].present? ? true : nil
123
82
  }.keep_if &value_present
124
83
  end
125
84
 
126
- def processed_is_and_format
85
+ def is_and_format
127
86
  result = { is: _is }
128
87
  # `format` that generated in process_type() may be overwrote here.
129
88
  result[:format] = _format || _is if processed[:format].blank? || _format.present?
130
89
  result
131
90
  end
132
91
 
92
+ def pattern_default_and_other
93
+ {
94
+ pattern: _pattern.is_a?(String)? _pattern : _pattern&.inspect&.delete('/'),
95
+ default: _default,
96
+ examples: self[:examples].present? ? ExampleObj.new(self[:examples], self[:exp_by]).process : nil,
97
+ as: _as, permit: _permit, not_permit: _npermit, req_if: _req_if, opt_if: _opt_if, blankable: _blank
98
+ }
99
+ end
100
+
133
101
 
134
102
  { # SELF_MAPPING
135
103
  _enum: %i[ enum in values allowable_values ],
@@ -151,11 +119,7 @@ module OpenApi
151
119
  }.each do |key, aliases|
152
120
  define_method key do
153
121
  return self[key] unless self[key].nil?
154
-
155
- aliases.each do |alias_name|
156
- break if self[key] == false
157
- self[key] ||= self[alias_name]
158
- end
122
+ aliases.each { |alias_name| self[key] = self[alias_name] if self[key].nil? }
159
123
  self[key]
160
124
  end
161
125
  define_method "#{key}=" do |value| self[key] = value end
@@ -1,23 +1,23 @@
1
1
  module OpenApi
2
2
  module DSL
3
3
  module SchemaObjHelpers
4
- # TODO: more info and desc configure
5
- def auto_generate_desc
6
- return __desc if processed[:enum].blank?
4
+ def hash_type(t)
5
+ # For supporting this:
6
+ # form 'desc', type: {
7
+ # id!: { type: Integer, enum: 0..5, desc: 'user id' }
8
+ # }, should have description within schema
9
+ if t.key?(:type)
10
+ SchemaObj.new(t[:type], t).process(inside_desc: true)
7
11
 
8
- if @enum_info.present?
9
- @enum_info.each_with_index do |(info, value), index|
10
- __desc.concat "<br/>#{index + 1}/ #{info}: #{value}"
11
- end
12
+ # For supporting combined schema in nested schema.
13
+ elsif (t.keys & %i[ one_of any_of all_of not ]).present?
14
+ CombinedSchema.new(t).process(inside_desc: true)
12
15
  else
13
- processed[:enum].each_with_index do |value, index|
14
- __desc.concat "<br/>#{index + 1}/ #{value}"
15
- end
16
+ obj_type(t)
16
17
  end
17
- __desc
18
18
  end
19
19
 
20
- def processed_obj_type(t)
20
+ def obj_type(t)
21
21
  obj_type = { type: 'object', properties: { }, required: [ ] }
22
22
 
23
23
  t.each do |prop_name, prop_type|
@@ -27,7 +27,7 @@ module OpenApi
27
27
  obj_type.keep_if &value_present
28
28
  end
29
29
 
30
- def processed_array_type(t)
30
+ def array_type(t)
31
31
  t = t.size == 1 ? t.first : { one_of: t }
32
32
  {
33
33
  type: 'array',
@@ -36,16 +36,16 @@ module OpenApi
36
36
  end
37
37
 
38
38
  def process_range_enum_and_lth
39
- self[:_enum] = str_range_2a(_enum) if _enum.present? && _enum.is_a?(Range)
40
- self[:_length] = str_range_2a(_length) if _length.present? && _length.is_a?(Range)
39
+ self[:_enum] = str_range_toa(_enum) if _enum.is_a?(Range)
40
+ self[:_length] = str_range_toa(_length) if _length.is_a?(Range)
41
41
 
42
42
  values = _enum || _value
43
43
  self._enum = Array(values) if truly_present?(values)
44
44
  end
45
45
 
46
- def str_range_2a(val)
46
+ def str_range_toa(val)
47
47
  val_class = val.first.class
48
- action = "to_#{val_class.to_s.downcase[0]}".to_sym
48
+ action = :"to_#{val_class.to_s.downcase[0]}"
49
49
  (val.first.to_s..val.last.to_s).to_a.map(&action)
50
50
  end
51
51
 
@@ -55,10 +55,26 @@ module OpenApi
55
55
  # 'all_desc': :all,
56
56
  # 'one_desc': :one
57
57
  # }
58
- self._enum ||= self[:enum!]
59
- return unless self[:enum!].is_a? Hash
60
- @enum_info = self[:enum!]
61
- self._enum = self[:enum!].values
58
+ self._enum ||= e = self[:enum!]
59
+ return unless e.is_a? Hash
60
+ @enum_info = e
61
+ self._enum = e.values
62
+ end
63
+
64
+ # TODO: more info and desc configure
65
+ def auto_generate_desc
66
+ return __desc if _enum.blank?
67
+
68
+ if @enum_info.present?
69
+ @enum_info.each_with_index do |(info, value), index|
70
+ __desc.concat "<br/>#{index + 1}/ #{info}: #{value}"
71
+ end
72
+ else
73
+ _enum.each_with_index do |value, index|
74
+ __desc.concat "<br/>#{index + 1}/ #{value}"
75
+ end
76
+ end
77
+ __desc
62
78
  end
63
79
  end
64
80
  end
@@ -28,27 +28,22 @@ module OpenApi
28
28
  self[:description] = desc
29
29
  end
30
30
 
31
- def param param_type, name, type, required, schema_hash = { }
31
+ def param param_type, name, type, required, schema_info = { }
32
32
  return if param_skip.include?(name)
33
33
  return if param_use.present? && param_use.exclude?(name)
34
34
 
35
- _t = nil
36
- schema_hash[:desc] ||= _t if (_t = param_descs[name]).present?
37
- schema_hash[:desc!] ||= _t if (_t = param_descs["#{name}!".to_sym]).present?
38
-
39
- param_obj = ParamObj.new(name, param_type, type, required, schema_hash)
35
+ schema_info[:desc] ||= param_descs[name]
36
+ schema_info[:desc!] ||= param_descs[:"#{name}!"]
37
+ param_obj = ParamObj.new(name, param_type, type, required, schema_info)
40
38
  # The definition of the same name parameter will be overwritten
41
39
  fill_in_parameters(param_obj)
42
40
  end
43
41
 
44
42
  # [ header header! path path! query query! cookie cookie! ]
45
- def _param_agent name, type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash
46
- combined_schema = one_of || all_of || any_of || (_not = binding.local_variable_get(:not))
47
- type = schema_hash[:type] ||= type
48
- pp "[ZRO] Syntax Error: param `#{name}` has no schema type!" and return if type.nil? && combined_schema.nil?
49
-
50
- schema_hash = CombinedSchema.new(one_of: one_of, all_of: all_of, any_of: any_of, _not: _not) if combined_schema
51
- param @param_type.to_s.delete('!'), name, type, (@param_type['!'] ? :req : :opt), schema_hash
43
+ def _param_agent name, type = nil, **schema_info
44
+ schema = process_schema_info(type, schema_info)
45
+ return puts ' ZRO'.red + " Syntax Error: param `#{name}` has no schema type!" if schema[:illegal?]
46
+ param @param_type, name, schema[:type], @necessity, schema[:combined] || schema[:info]
52
47
  end
53
48
 
54
49
  # For supporting this: (just like `form '', data: { }` usage)
@@ -58,17 +53,17 @@ module OpenApi
58
53
  # }
59
54
  %i[ header header! path path! query query! cookie cookie! ].each do |param_type|
60
55
  define_method "do_#{param_type}" do |by:, **common_schema|
61
- by.each do |p_name, schema|
62
- action = param_type.to_s.delete('!')
56
+ by.each do |param_name, schema|
57
+ action = "#{param_type}#{param_name['!']}".sub('!!', '!')
63
58
  type, schema = schema.is_a?(Hash) ? [schema[:type], schema] : [schema, { }]
64
- args = [ p_name.to_s.delete('!').to_sym, type, schema.reverse_merge!(common_schema) ]
65
- param_type['!'] || p_name['!'] ? send("#{action}!", *args) : send(action, *args)
59
+ args = [ param_name.to_s.delete('!').to_sym, type, schema.reverse_merge!(common_schema) ]
60
+ send(action, *args)
66
61
  end
67
62
  end
68
63
  end
69
64
 
70
65
  def param_ref component_key, *keys
71
- self[:parameters].concat([component_key].concat(keys).map { |key| RefObj.new(:parameter, key).process })
66
+ self[:parameters] += [component_key, *keys].map { |key| RefObj.new(:parameter, key) }
72
67
  end
73
68
 
74
69
  # options: `exp_by` and `examples`
@@ -80,7 +75,7 @@ module OpenApi
80
75
 
81
76
  # [ body body! ]
82
77
  def _request_body_agent media_type, data: { }, **options
83
- request_body (@method_name['!'] ? :req : :opt), media_type, data: data, **options
78
+ request_body @necessity, media_type, data: data, **options
84
79
  end
85
80
 
86
81
  def body_ref component_key
@@ -95,9 +90,9 @@ module OpenApi
95
90
  body! :form, data: data, **options
96
91
  end
97
92
 
98
- def data name, type = nil, schema_hash = { }
99
- schema_hash[:type] = type if type.present?
100
- form data: { name => schema_hash }
93
+ def data name, type = nil, schema_info = { }
94
+ schema_info[:type] = type if type.present?
95
+ form data: { name => schema_info }
101
96
  end
102
97
 
103
98
  def file media_type, data: { type: File }, **options
@@ -109,9 +104,7 @@ module OpenApi
109
104
  end
110
105
 
111
106
  def response_ref code_compkey_hash
112
- code_compkey_hash.each do |code, component_key|
113
- self[:responses][code] = RefObj.new(:response, component_key).process
114
- end
107
+ code_compkey_hash.each { |code, component_key| self[:responses][code] = RefObj.new(:response, component_key) }
115
108
  end
116
109
 
117
110
  def security_require scheme_name, scopes: [ ]
@@ -128,34 +121,24 @@ module OpenApi
128
121
 
129
122
  def order *param_names
130
123
  self.param_order = param_names
131
- # use when api_dry
124
+ # be used when `api_dry`
132
125
  self.param_use = param_order if param_use.blank?
133
126
  self.param_skip = param_use - param_order
134
127
  end
135
128
 
136
129
  def param_examples exp_by = :all, examples_hash
137
- process_objs
138
- exp_by = self[:parameters].map { |p| p[:name] } if exp_by == :all
130
+ exp_by = self[:parameters].map(&:name) if exp_by == :all
139
131
  self[:examples] = ExampleObj.new(examples_hash, exp_by).process
140
132
  end
141
133
 
142
134
  alias examples param_examples
143
135
 
144
136
  def process_objs
145
- self[:parameters]&.each_with_index do |p, index|
146
- self[:parameters][index] = p.process if p.is_a?(ParamObj)
147
- end
137
+ self[:parameters].map!(&:process)
138
+ self[:parameters].sort_by! { |param| param_order.index(param[:name]) || Float::INFINITY } if param_order.present?
148
139
 
149
- # Parameters sorting
150
- self[:parameters].clone.each do |p|
151
- self[:parameters][param_order.index(p[:name]) || -1] = p
152
- end if param_order.present?
153
-
154
- self[:requestBody] = self[:requestBody].try :process
155
-
156
- self[:responses]&.each do |code, obj|
157
- self[:responses][code] = obj.process if obj.is_a?(ResponseObj)
158
- end
140
+ self[:requestBody] = self[:requestBody].try(:process)
141
+ self[:responses].each { |code, response| self[:responses][code] = response.process }
159
142
  end
160
143
  end
161
144
  end
@@ -12,14 +12,15 @@ module OpenApi
12
12
  module CommonDSL
13
13
  %i[ header header! path path! query query! cookie cookie! ].each do |param_type|
14
14
  define_method param_type do |*args|
15
- @param_type = param_type
15
+ @necessity = param_type['!'] ? :req : :opt
16
+ @param_type = param_type.to_s.delete('!') # OR: caller[0][/`.*'/][1..-2].to_sym
16
17
  _param_agent *args
17
18
  end
18
19
  end
19
20
 
20
21
  %i[ body body! ].each do |method|
21
22
  define_method method do |*args|
22
- @method_name = method
23
+ @necessity = method['!'] ? :req : :opt
23
24
  _request_body_agent *args
24
25
  end
25
26
  end
@@ -6,51 +6,44 @@ module OpenApi
6
6
  include DSL::CommonDSL
7
7
  include DSL::Helpers
8
8
 
9
- def schema component_key, type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash
10
- combined_schema = (_not = binding.local_variable_get(:not)) || one_of || all_of || any_of
11
- schema_hash[:type] ||= type
12
- schema_hash = load_schema component_key if component_key.try(:superclass) == (Config.active_record_base || ApplicationRecord)
13
- pp "[ZRO] Syntax Error: component schema `#{component_key}` has no type!" and return if schema_hash[:type].nil? && combined_schema.nil?
14
-
15
- combined_schema = CombinedSchema.new(one_of: one_of, all_of: all_of, any_of: any_of, _not: _not) if combined_schema
16
- (self[:schemas] ||= { })[component_key.to_s.to_sym] = combined_schema&.process || SchemaObj.new(schema_hash, { }).process
9
+ def schema component_key, type = nil, **schema_info
10
+ schema = process_schema_info(type, schema_info, model: component_key)
11
+ return puts ' ZRO'.red + " Syntax Error: component schema `#{component_key}` has no type!" if schema[:illegal?]
12
+ self[:schemas][component_key.to_s.to_sym] = (schema[:combined] || SchemaObj.new(type = schema[:info], { })).process
17
13
  end
14
+
18
15
  arrow_enable :schema
19
16
 
20
17
  def example component_key, examples_hash
21
- (self[:examples] ||= { })[component_key] = ExampleObj.new(examples_hash).process
18
+ self[:examples][component_key] = ExampleObj.new(examples_hash).process
22
19
  end
20
+
23
21
  arrow_enable :example
24
22
 
25
- def param component_key, param_type, name, type, required, schema_hash = { }
26
- (self[:parameters] ||= { })[component_key] = ParamObj.new(name, param_type, type, required, schema_hash).process
23
+ def param component_key, param_type, name, type, required, schema_info = { }
24
+ self[:parameters][component_key] = ParamObj.new(name, param_type, type, required, schema_info).process
27
25
  end
28
26
 
29
27
  # [ header header! path path! query query! cookie cookie! ]
30
- def _param_agent component_key, name, type = nil, one_of: nil, all_of: nil, any_of: nil, not: nil, **schema_hash
31
- combined_schema = one_of || all_of || any_of || (_not = binding.local_variable_get(:not))
32
- schema_hash[:type] ||= type
33
- pp "[ZRO] Syntax Error: param `#{name}` has no schema type!" and return if schema_hash[:type].nil? && combined_schema.nil?
34
-
35
- combined_schema = one_of || all_of || any_of || (_not = binding.local_variable_get(:not))
36
- schema_hash = CombinedSchema.new(one_of: one_of, all_of: all_of, any_of: any_of, _not: _not) if combined_schema
37
- param component_key,
38
- "#{@param_type}".delete('!'), name, type, (@param_type['!'] ? :req : :opt), schema_hash
28
+ def _param_agent component_key, name, type = nil, **schema_info
29
+ schema = process_schema_info(type, schema_info)
30
+ return puts ' ZRO'.red + " Syntax Error: param `#{name}` has no schema type!" if schema[:illegal?]
31
+ param component_key, @param_type, name, schema[:type], @necessity, schema[:combined] || schema[:info]
39
32
  end
33
+
40
34
  arrow_enable :_param_agent
41
35
 
42
- def request_body component_key, required, media_type, data: { }, **options
43
- desc = options.delete(:desc) || ''
44
- cur = (self[:requestBodies] ||= { })[component_key]
36
+ def request_body component_key, required, media_type, data: { }, desc: '', **options
37
+ cur = self[:requestBodies][component_key]
45
38
  cur = RequestBodyObj.new(required, desc) unless cur.is_a?(RequestBodyObj)
46
39
  self[:requestBodies][component_key] = cur.add_or_fusion(media_type, { data: data, **options })
47
40
  end
48
41
 
49
42
  # [ body body! ]
50
43
  def _request_body_agent component_key, media_type, data: { }, **options
51
- request_body component_key,
52
- (@method_name['!'] ? :req : :opt), media_type, data: data, **options
44
+ request_body component_key, @necessity, media_type, data: data, **options
53
45
  end
46
+
54
47
  arrow_enable :_request_body_agent
55
48
 
56
49
  arrow_enable :resp # alias_method 竟然也会指向旧的方法?
@@ -58,8 +51,9 @@ module OpenApi
58
51
 
59
52
  def security_scheme scheme_name, other_info# = { }
60
53
  other_info[:description] = other_info.delete(:desc) if other_info[:desc]
61
- (self[:securitySchemes] ||= { })[scheme_name] = other_info
54
+ self[:securitySchemes][scheme_name] = other_info
62
55
  end
56
+
63
57
  arrow_enable :security_scheme
64
58
 
65
59
  alias auth_scheme security_scheme
@@ -67,27 +61,25 @@ module OpenApi
67
61
  def base_auth scheme_name, other_info = { }
68
62
  security_scheme scheme_name, { type: 'http', scheme: 'basic', **other_info }
69
63
  end
64
+
70
65
  arrow_enable :base_auth
71
66
 
72
67
  def bearer_auth scheme_name, format = 'JWT', other_info = { }
73
68
  security_scheme scheme_name, { type: 'http', scheme: 'bearer', bearerFormat: format, **other_info }
74
69
  end
70
+
75
71
  arrow_enable :bearer_auth
76
72
 
77
73
  def api_key scheme_name, field:, in: 'header', **other_info
78
74
  _in = binding.local_variable_get(:in)
79
75
  security_scheme scheme_name, { type: 'apiKey', name: field, in: _in, **other_info }
80
76
  end
77
+
81
78
  arrow_enable :api_key
82
79
 
83
80
  def process_objs
84
- self[:requestBodies]&.each do |key, obj|
85
- self[:requestBodies][key] = obj.process
86
- end
87
-
88
- self[:responses]&.each do |code, obj|
89
- self[:responses][code] = obj.process if obj.is_a?(ResponseObj)
90
- end
81
+ self[:requestBodies].each { |key, body| self[:requestBodies][key] = body.process }
82
+ self[:responses].each { |code, response| self[:responses][code] = response.process }
91
83
  end
92
84
  end
93
85
  end
@@ -6,11 +6,11 @@ module OpenApi
6
6
  end
7
7
 
8
8
  # :nocov:
9
- def load_schema(model)
9
+ def load_schema(model) # TODO: test
10
10
  # About `show_attrs`, see:
11
11
  # (1) BuilderSupport module: https://github.com/zhandao/zero-rails/blob/master/app/models/concerns/builder_support.rb
12
12
  # (2) config in model: https://github.com/zhandao/zero-rails/tree/master/app/models/good.rb
13
- # (3) jbuilder file: https://github.com/zhandao/zero-rails/blob/mster/app/views/api/v1/goods/index.json.jbuilder
13
+ # (3) jbuilder file: https://github.com/zhandao/zero-rails/blob/master/app/views/api/v1/goods/index.json.jbuilder
14
14
  # In a word, BuilderSupport let you control the `output fields and nested association infos` very easily.
15
15
  if model.respond_to? :show_attrs
16
16
  _load_schema_based_on_show_attr(model)
@@ -41,27 +41,43 @@ module OpenApi
41
41
  # :nocov:
42
42
 
43
43
  def fill_in_parameters(param_obj)
44
- name = param_obj.processed[:name]
45
- index = self[:parameters].map { |p| p.processed[:name] if p.is_a?(ParamObj) }.index(name)
44
+ index = self[:parameters].map(&:name).index(param_obj.name)
46
45
  index.present? ? self[:parameters][index] = param_obj : self[:parameters] << param_obj
47
46
  end
48
47
 
48
+ def _combined_schema(one_of: nil, all_of: nil, any_of: nil, not: nil, **other)
49
+ input = (_not = binding.local_variable_get(:not)) || one_of || all_of || any_of
50
+ CombinedSchema.new(one_of: one_of, all_of: all_of, any_of: any_of, _not: _not) if input
51
+ end
52
+
53
+ def process_schema_info(schema_type, schema_info, model: nil)
54
+ combined_schema = _combined_schema(schema_info)
55
+ type = schema_info[:type] ||= schema_type
56
+ schema_info = load_schema(model) if model.try(:superclass) == (Config.active_record_base || ApplicationRecord)
57
+ {
58
+ illegal?: type.nil? && combined_schema.nil?,
59
+ combined: combined_schema,
60
+ info: schema_info,
61
+ type: type
62
+ }
63
+ end
64
+
49
65
  # Arrow Writing:
50
66
  # response :RespComponent => [ '200', 'success', :json ]
51
67
  # It is equivalent to:
52
68
  # response :RespComponent, '200', 'success', :json
53
69
  # But I think, in the definition of a component,
54
- # the key-value (arrow) writing is easy to understand.
70
+ # the key-value (arrow) writing is more easier to understand.
55
71
  def arrow_writing_support
56
72
  proc do |args, executor|
57
- _args = (args.size == 1 && args.first.is_a?(Hash)) ? args[0].to_a.flatten : args
58
- send(executor, *_args)
73
+ args = (args.size == 1 && args.first.is_a?(Hash)) ? args[0].to_a.flatten : args
74
+ send(executor, *args)
59
75
  end
60
76
  end
61
77
 
62
78
  module ClassMethods
63
79
  def arrow_enable method
64
- alias_method "_#{method}".to_sym, method
80
+ alias_method :"_#{method}", method
65
81
  define_method method do |*args|
66
82
  arrow_writing_support.call(args, "_#{method}")
67
83
  end