jsapi 1.2 → 1.4
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/lib/jsapi/configuration.rb +2 -2
- data/lib/jsapi/controller/methods.rb +17 -4
- data/lib/jsapi/controller/parameters.rb +26 -13
- data/lib/jsapi/controller/response.rb +29 -5
- data/lib/jsapi/dsl/class_methods.rb +11 -0
- data/lib/jsapi/dsl/definitions.rb +14 -0
- data/lib/jsapi/dsl/path.rb +43 -0
- data/lib/jsapi/dsl.rb +1 -0
- data/lib/jsapi/meta/callback/base.rb +1 -1
- data/lib/jsapi/meta/definitions.rb +98 -24
- data/lib/jsapi/meta/example/base.rb +4 -6
- data/lib/jsapi/meta/link/base.rb +4 -2
- data/lib/jsapi/meta/oauth_flow.rb +11 -2
- data/lib/jsapi/meta/openapi/path_item.rb +68 -0
- data/lib/jsapi/meta/openapi/version.rb +6 -0
- data/lib/jsapi/meta/openapi.rb +2 -0
- data/lib/jsapi/meta/operation.rb +29 -17
- data/lib/jsapi/meta/parameter/base.rb +82 -59
- data/lib/jsapi/meta/path.rb +56 -0
- data/lib/jsapi/meta/pathname.rb +60 -0
- data/lib/jsapi/meta/request_body/base.rb +3 -2
- data/lib/jsapi/meta/response/base.rb +26 -8
- data/lib/jsapi/meta/schema/base.rb +1 -1
- data/lib/jsapi/meta/schema/discriminator.rb +14 -4
- data/lib/jsapi/meta/schema/object.rb +28 -9
- data/lib/jsapi/meta/schema/validation/maximum.rb +1 -1
- data/lib/jsapi/meta/schema/validation/minimum.rb +1 -1
- data/lib/jsapi/meta/security_scheme/api_key.rb +4 -5
- data/lib/jsapi/meta/security_scheme/base.rb +16 -0
- data/lib/jsapi/meta/security_scheme/http/basic.rb +3 -10
- data/lib/jsapi/meta/security_scheme/http/bearer.rb +8 -8
- data/lib/jsapi/meta/security_scheme/http/other.rb +3 -5
- data/lib/jsapi/meta/security_scheme/mutual_tls.rb +23 -0
- data/lib/jsapi/meta/security_scheme/oauth2.rb +29 -13
- data/lib/jsapi/meta/security_scheme/open_id_connect.rb +5 -8
- data/lib/jsapi/meta/security_scheme.rb +3 -0
- data/lib/jsapi/meta/server.rb +9 -1
- data/lib/jsapi/meta/tag.rb +34 -4
- data/lib/jsapi/meta.rb +2 -0
- data/lib/jsapi/version.rb +1 -1
- metadata +7 -2
data/lib/jsapi/meta/operation.rb
CHANGED
|
@@ -28,18 +28,8 @@ module Jsapi
|
|
|
28
28
|
|
|
29
29
|
##
|
|
30
30
|
# :attr: method
|
|
31
|
-
# The HTTP
|
|
32
|
-
|
|
33
|
-
# - <code>"delete"</code>
|
|
34
|
-
# - <code>"get"</code>
|
|
35
|
-
# - <code>"head"</code>
|
|
36
|
-
# - <code>"options"</code>
|
|
37
|
-
# - <code>"patch"</code>
|
|
38
|
-
# - <code>"post"</code>
|
|
39
|
-
# - <code>"put"</code>
|
|
40
|
-
#
|
|
41
|
-
# The default HTTP verb is <code>"get"</code>.
|
|
42
|
-
attribute :method, values: %w[delete get head options patch post put], default: 'get'
|
|
31
|
+
# The HTTP method of the operation, <code>"get"</code> by default.
|
|
32
|
+
attribute :method, String, default: 'get'
|
|
43
33
|
|
|
44
34
|
##
|
|
45
35
|
# :attr: model
|
|
@@ -56,10 +46,15 @@ module Jsapi
|
|
|
56
46
|
# The parameters of the operation.
|
|
57
47
|
attribute :parameters, { String => Parameter }, accessors: %i[reader writer]
|
|
58
48
|
|
|
49
|
+
##
|
|
50
|
+
# :attr_reader: parent_path
|
|
51
|
+
# The parent path as a Pathname.
|
|
52
|
+
attribute :parent_path, Pathname, accessors: %i[reader]
|
|
53
|
+
|
|
59
54
|
##
|
|
60
55
|
# :attr: path
|
|
61
|
-
# The relative path of the operation.
|
|
62
|
-
attribute :path,
|
|
56
|
+
# The relative path of the operation as a Pathname.
|
|
57
|
+
attribute :path, Pathname
|
|
63
58
|
|
|
64
59
|
##
|
|
65
60
|
# :attr: request_body
|
|
@@ -97,7 +92,7 @@ module Jsapi
|
|
|
97
92
|
|
|
98
93
|
##
|
|
99
94
|
# :attr: summary
|
|
100
|
-
# The short
|
|
95
|
+
# The short description of the operation.
|
|
101
96
|
attribute :summary, String
|
|
102
97
|
|
|
103
98
|
##
|
|
@@ -105,8 +100,11 @@ module Jsapi
|
|
|
105
100
|
# The tags used to group operations in an \OpenAPI document.
|
|
106
101
|
attribute :tags, [String]
|
|
107
102
|
|
|
108
|
-
def initialize(name = nil, keywords = {})
|
|
103
|
+
def initialize(name, parent_path = nil, keywords = {})
|
|
104
|
+
parent_path, keywords = nil, parent_path if parent_path.is_a?(Hash)
|
|
105
|
+
|
|
109
106
|
@name = name&.to_s
|
|
107
|
+
@parent_path = Pathname.from(parent_path)
|
|
110
108
|
super(keywords)
|
|
111
109
|
end
|
|
112
110
|
|
|
@@ -114,6 +112,11 @@ module Jsapi
|
|
|
114
112
|
(@parameters ||= {})[name.to_s] = Parameter.new(name, keywords)
|
|
115
113
|
end
|
|
116
114
|
|
|
115
|
+
# Returns the full path of the operation as a Pathname.
|
|
116
|
+
def full_path
|
|
117
|
+
parent_path + path
|
|
118
|
+
end
|
|
119
|
+
|
|
117
120
|
# Returns the MIME type consumed by the operation.
|
|
118
121
|
def consumes(definitions)
|
|
119
122
|
request_body&.resolve(definitions)&.content_type
|
|
@@ -126,6 +129,13 @@ module Jsapi
|
|
|
126
129
|
end.uniq.sort
|
|
127
130
|
end
|
|
128
131
|
|
|
132
|
+
# Merges the parameters of this operation and the common parameters of all
|
|
133
|
+
# parent pathes and resolves them.
|
|
134
|
+
def resolved_parameters(definitions)
|
|
135
|
+
(definitions.path_parameters(full_path).presence&.merge(parameters) || parameters)
|
|
136
|
+
.transform_values { |parameter| parameter.resolve(definitions) }
|
|
137
|
+
end
|
|
138
|
+
|
|
129
139
|
# Returns a hash representing the \OpenAPI operation object.
|
|
130
140
|
def to_openapi(version, definitions)
|
|
131
141
|
version = OpenAPI::Version.from(version)
|
|
@@ -148,7 +158,9 @@ module Jsapi
|
|
|
148
158
|
end
|
|
149
159
|
result[:schemes] = schemes if schemes.present?
|
|
150
160
|
elsif servers.present?
|
|
151
|
-
result[:servers] = servers.map
|
|
161
|
+
result[:servers] = servers.map do |server|
|
|
162
|
+
server.to_openapi(version)
|
|
163
|
+
end
|
|
152
164
|
end
|
|
153
165
|
# Parameters (and request body)
|
|
154
166
|
result[:parameters] = parameters.values.flat_map do |parameter|
|
|
@@ -9,6 +9,11 @@ module Jsapi
|
|
|
9
9
|
|
|
10
10
|
delegate_missing_to :schema
|
|
11
11
|
|
|
12
|
+
##
|
|
13
|
+
# :attr: content_type
|
|
14
|
+
# The content type used to describe complex parameters in \OpenAPI 3.0 and higher.
|
|
15
|
+
attribute :content_type, String
|
|
16
|
+
|
|
12
17
|
##
|
|
13
18
|
# :attr: deprecated
|
|
14
19
|
# Specifies whether or not the parameter is deprecated.
|
|
@@ -31,9 +36,10 @@ module Jsapi
|
|
|
31
36
|
# - <code>"header"</code>
|
|
32
37
|
# - <code>"path"</code>
|
|
33
38
|
# - <code>"query"</code>
|
|
39
|
+
# - <code>"querystring"</code>
|
|
34
40
|
#
|
|
35
41
|
# The default location is <code>"query"</code>.
|
|
36
|
-
attribute :in, String, values: %w[header path query], default: 'query'
|
|
42
|
+
attribute :in, String, values: %w[header path query querystring], default: 'query'
|
|
37
43
|
|
|
38
44
|
##
|
|
39
45
|
# :attr_reader: name
|
|
@@ -54,8 +60,16 @@ module Jsapi
|
|
|
54
60
|
@name = name.to_s
|
|
55
61
|
|
|
56
62
|
keywords = keywords.dup
|
|
57
|
-
super(
|
|
58
|
-
|
|
63
|
+
super(
|
|
64
|
+
keywords.extract!(
|
|
65
|
+
:content_type,
|
|
66
|
+
:deprecated,
|
|
67
|
+
:description,
|
|
68
|
+
:examples,
|
|
69
|
+
:in,
|
|
70
|
+
:openapi_extensions
|
|
71
|
+
)
|
|
72
|
+
)
|
|
59
73
|
add_example(value: keywords.delete(:example)) if keywords.key?(:example)
|
|
60
74
|
keywords[:ref] = keywords.delete(:schema) if keywords.key?(:schema)
|
|
61
75
|
|
|
@@ -75,12 +89,13 @@ module Jsapi
|
|
|
75
89
|
# Returns a hash representing the \OpenAPI parameter object.
|
|
76
90
|
def to_openapi(version, definitions)
|
|
77
91
|
version = OpenAPI::Version.from(version)
|
|
78
|
-
schema = self.schema.resolve(definitions)
|
|
79
92
|
|
|
80
|
-
|
|
93
|
+
openapi_parameter_object(
|
|
81
94
|
name,
|
|
82
|
-
schema,
|
|
95
|
+
schema.resolve(definitions),
|
|
83
96
|
version,
|
|
97
|
+
location: self.in,
|
|
98
|
+
content_type: content_type || ('text/plain' if self.in == 'querystring'),
|
|
84
99
|
description: description,
|
|
85
100
|
required: required?,
|
|
86
101
|
deprecated: deprecated?,
|
|
@@ -92,39 +107,30 @@ module Jsapi
|
|
|
92
107
|
# Returns an array of hashes representing the \OpenAPI parameter objects.
|
|
93
108
|
def to_openapi_parameters(version, definitions)
|
|
94
109
|
version = OpenAPI::Version.from(version)
|
|
110
|
+
is_querystring = self.in == 'querystring'
|
|
95
111
|
schema = self.schema.resolve(definitions)
|
|
96
112
|
|
|
97
|
-
if schema.object?
|
|
113
|
+
if schema.object? && (version < OpenAPI::V3_2 || !is_querystring)
|
|
98
114
|
explode_parameter(
|
|
99
|
-
name,
|
|
115
|
+
is_querystring ? nil : name,
|
|
100
116
|
schema,
|
|
101
117
|
version,
|
|
102
118
|
definitions,
|
|
119
|
+
location: is_querystring ? 'query' : self.in,
|
|
103
120
|
required: required?,
|
|
104
121
|
deprecated: deprecated?
|
|
105
122
|
)
|
|
106
123
|
else
|
|
107
|
-
[
|
|
108
|
-
|
|
109
|
-
name,
|
|
110
|
-
schema,
|
|
111
|
-
version,
|
|
112
|
-
description: description,
|
|
113
|
-
required: required?,
|
|
114
|
-
deprecated: deprecated?,
|
|
115
|
-
allow_empty_value: allow_empty_value?,
|
|
116
|
-
examples: examples
|
|
117
|
-
)
|
|
118
|
-
]
|
|
119
|
-
end
|
|
124
|
+
[to_openapi(version, definitions)]
|
|
125
|
+
end.compact
|
|
120
126
|
end
|
|
121
127
|
|
|
122
128
|
private
|
|
123
129
|
|
|
124
|
-
def explode_parameter(name, schema, version, definitions, required:, deprecated:)
|
|
130
|
+
def explode_parameter(name, schema, version, definitions, location:, required:, deprecated:)
|
|
125
131
|
schema.resolve_properties(definitions, context: :request).values.flat_map do |property|
|
|
126
132
|
property_schema = property.schema.resolve(definitions)
|
|
127
|
-
parameter_name = "#{name}[#{property.name}]"
|
|
133
|
+
parameter_name = name ? "#{name}[#{property.name}]" : property.name
|
|
128
134
|
required = (required && property.required?).presence
|
|
129
135
|
deprecated = (deprecated || property_schema.deprecated?).presence
|
|
130
136
|
|
|
@@ -134,62 +140,79 @@ module Jsapi
|
|
|
134
140
|
property_schema,
|
|
135
141
|
version,
|
|
136
142
|
definitions,
|
|
143
|
+
location: location,
|
|
137
144
|
required: required,
|
|
138
145
|
deprecated: deprecated
|
|
139
146
|
)
|
|
140
147
|
else
|
|
141
148
|
[
|
|
142
|
-
|
|
149
|
+
openapi_parameter_object(
|
|
143
150
|
parameter_name,
|
|
144
151
|
property_schema,
|
|
145
152
|
version,
|
|
153
|
+
location: location,
|
|
146
154
|
description: property_schema.description,
|
|
147
155
|
required: required,
|
|
148
156
|
deprecated: deprecated,
|
|
149
157
|
allow_empty_value: property.schema.existence <= Existence::ALLOW_EMPTY
|
|
150
158
|
)
|
|
151
159
|
]
|
|
152
|
-
end
|
|
160
|
+
end.compact
|
|
153
161
|
end
|
|
154
162
|
end
|
|
155
163
|
|
|
156
|
-
def
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
164
|
+
def openapi_parameter_object(name, schema, version,
|
|
165
|
+
allow_empty_value:,
|
|
166
|
+
deprecated:,
|
|
167
|
+
description:,
|
|
168
|
+
location:,
|
|
169
|
+
required:,
|
|
170
|
+
content_type: nil,
|
|
171
|
+
examples: nil)
|
|
162
172
|
|
|
163
|
-
|
|
173
|
+
return if location == 'querystring' && version < OpenAPI::V3_2
|
|
174
|
+
|
|
175
|
+
if schema.object? && version == OpenAPI::V2_0
|
|
176
|
+
raise "OpenAPI 2.0 doesn't allow object parameters in #{location}"
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
name = "#{name}[]" if schema.array?
|
|
164
180
|
|
|
165
181
|
with_openapi_extensions(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
182
|
+
name: name,
|
|
183
|
+
in: location,
|
|
184
|
+
description: description,
|
|
185
|
+
required: required.presence,
|
|
186
|
+
allowEmptyValue: allow_empty_value.presence,
|
|
187
|
+
**if version == OpenAPI::V2_0
|
|
188
|
+
{
|
|
189
|
+
collectionFormat: ('multi' if schema.array?),
|
|
190
|
+
**schema.to_openapi(version)
|
|
191
|
+
}
|
|
192
|
+
else
|
|
193
|
+
openapi_schema = schema.to_openapi(version).except(:deprecated)
|
|
194
|
+
openapi_examples = examples&.transform_values(&:to_openapi).presence
|
|
195
|
+
{
|
|
196
|
+
deprecated: deprecated.presence,
|
|
197
|
+
**if content_type.blank?
|
|
198
|
+
# simple scenario
|
|
199
|
+
{
|
|
200
|
+
schema: openapi_schema,
|
|
201
|
+
examples: openapi_examples
|
|
202
|
+
}
|
|
203
|
+
else
|
|
204
|
+
# complex scenario
|
|
205
|
+
{
|
|
206
|
+
content: {
|
|
207
|
+
content_type => {
|
|
208
|
+
schema: openapi_schema,
|
|
209
|
+
examples: openapi_examples
|
|
210
|
+
}.compact
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
end
|
|
214
|
+
}
|
|
215
|
+
end
|
|
193
216
|
)
|
|
194
217
|
end
|
|
195
218
|
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jsapi
|
|
4
|
+
module Meta
|
|
5
|
+
# Specifies a path.
|
|
6
|
+
class Path < Model::Base
|
|
7
|
+
##
|
|
8
|
+
# :attr: description
|
|
9
|
+
# The description that applies to all operations in this path.
|
|
10
|
+
# Applies to \OpenAPI 3.0 and higher.
|
|
11
|
+
attribute :description, String
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# :attr_reader: name
|
|
15
|
+
# The relative path as a Pathname.
|
|
16
|
+
attribute :name, Pathname, accessors: %i[reader]
|
|
17
|
+
|
|
18
|
+
##
|
|
19
|
+
# :attr: parameters
|
|
20
|
+
# The Parameter objects applicable for all operations in this path.
|
|
21
|
+
attribute :parameters, { String => Parameter }, accessors: %i[reader writer]
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# :attr_reader: owner
|
|
25
|
+
attribute :owner, accessors: %i[reader]
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# :attr: summary
|
|
29
|
+
# The summary that applies to all operations in this path.
|
|
30
|
+
# Applies to \OpenAPI 3.0 and higher.
|
|
31
|
+
attribute :summary, String
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# :attr: servers
|
|
35
|
+
# The Server objects that applies to all operations in this path.
|
|
36
|
+
# Applies to \OpenAPI 3.0 and higher.
|
|
37
|
+
attribute :servers, [Server]
|
|
38
|
+
|
|
39
|
+
# Creates a new path with the given name and owner.
|
|
40
|
+
def initialize(name, owner, keywords = {})
|
|
41
|
+
@name = Pathname.from(name)
|
|
42
|
+
@owner = owner
|
|
43
|
+
super(keywords)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def add_parameter(name, keywords = {}) # :nodoc:
|
|
47
|
+
name = name.to_s
|
|
48
|
+
|
|
49
|
+
Parameter.new(name, keywords).tap do |parameter|
|
|
50
|
+
(@parameters ||= {})[name] = parameter
|
|
51
|
+
@owner.try(:invalidate_path_parameters, self.name)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jsapi
|
|
4
|
+
module Meta
|
|
5
|
+
# Represents a relative path name.
|
|
6
|
+
class Pathname
|
|
7
|
+
class << self
|
|
8
|
+
# Creates a Pathname from +name+.
|
|
9
|
+
def from(name)
|
|
10
|
+
return name if name.is_a?(Pathname)
|
|
11
|
+
|
|
12
|
+
name.nil? ? new : new(name)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_reader :segments
|
|
17
|
+
|
|
18
|
+
delegate :hash, to: :segments
|
|
19
|
+
|
|
20
|
+
def initialize(*segments) # :nodoc:
|
|
21
|
+
@segments = segments.flat_map do |segment|
|
|
22
|
+
segment = segment.to_s.delete_prefix('/')
|
|
23
|
+
segment.present? ? segment.split('/', -1) : ''
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def ==(other) # :nodoc:
|
|
28
|
+
other.is_a?(Pathname) && segments == other.segments
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
alias eql? ==
|
|
32
|
+
|
|
33
|
+
# Creates a new Pathname by appending +other+ to +self+.
|
|
34
|
+
# Returns +self+ if +other+ is nil.
|
|
35
|
+
def +(other)
|
|
36
|
+
return self if other.nil?
|
|
37
|
+
|
|
38
|
+
Pathname.new(*@segments, *Pathname.from(other).segments)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Returns an array containing itself and all parent pathnames.
|
|
42
|
+
def ancestors
|
|
43
|
+
@ancestors ||= @segments.count.downto(0).map do |i|
|
|
44
|
+
Pathname.new(*@segments[0, i])
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def inspect # :nodoc:
|
|
49
|
+
"#<#{self.class} #{to_s.inspect}>"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Returns the relative path name as a string.
|
|
53
|
+
def to_s
|
|
54
|
+
@to_s ||= @segments.presence&.each_with_index&.map do |segment, index|
|
|
55
|
+
index.zero? && segment.blank? ? '//' : "/#{segment}"
|
|
56
|
+
end&.join || '/'
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -8,12 +8,13 @@ module Jsapi
|
|
|
8
8
|
include OpenAPI::Extensions
|
|
9
9
|
|
|
10
10
|
JSON_TYPE = %r{(^application/|^text/|\+)json$}.freeze # :nodoc:
|
|
11
|
+
JSON_SEQ_TYPE = 'application/json-seq' # :nodoc:
|
|
11
12
|
|
|
12
13
|
delegate_missing_to :schema
|
|
13
14
|
|
|
14
15
|
##
|
|
15
16
|
# :attr: content_type
|
|
16
|
-
# The content type
|
|
17
|
+
# The content type, <code>"application/json"</code> by default.
|
|
17
18
|
attribute :content_type, String, default: 'application/json'
|
|
18
19
|
|
|
19
20
|
##
|
|
@@ -46,12 +47,17 @@ module Jsapi
|
|
|
46
47
|
# The Schema of the response.
|
|
47
48
|
attribute :schema, accessors: %i[reader]
|
|
48
49
|
|
|
50
|
+
##
|
|
51
|
+
# :attr: summary
|
|
52
|
+
# The short description of the response. Applies to \OpenAPI 3.2 and higher.
|
|
53
|
+
attribute :summary, String
|
|
54
|
+
|
|
49
55
|
def initialize(keywords = {})
|
|
50
56
|
keywords = keywords.dup
|
|
51
57
|
super(
|
|
52
58
|
keywords.extract!(
|
|
53
59
|
:content_type, :description, :examples, :headers,
|
|
54
|
-
:links, :locale, :openapi_extensions
|
|
60
|
+
:links, :locale, :openapi_extensions, :summary
|
|
55
61
|
)
|
|
56
62
|
)
|
|
57
63
|
add_example(value: keywords.delete(:example)) if keywords.key?(:example)
|
|
@@ -66,12 +72,17 @@ module Jsapi
|
|
|
66
72
|
content_type.match?(JSON_TYPE)
|
|
67
73
|
end
|
|
68
74
|
|
|
75
|
+
# Returns true if content type is <code>"application/json-seq"</code>.
|
|
76
|
+
def json_seq_type?
|
|
77
|
+
content_type == JSON_SEQ_TYPE
|
|
78
|
+
end
|
|
79
|
+
|
|
69
80
|
# Returns a hash representing the \OpenAPI response object.
|
|
70
81
|
def to_openapi(version, definitions)
|
|
71
82
|
version = OpenAPI::Version.from(version)
|
|
72
83
|
|
|
73
84
|
with_openapi_extensions(
|
|
74
|
-
if version
|
|
85
|
+
if version == OpenAPI::V2_0
|
|
75
86
|
{
|
|
76
87
|
description: description,
|
|
77
88
|
schema: schema.to_openapi(version),
|
|
@@ -86,17 +97,24 @@ module Jsapi
|
|
|
86
97
|
}
|
|
87
98
|
else
|
|
88
99
|
{
|
|
100
|
+
summary: (summary if version >= OpenAPI::V3_2),
|
|
89
101
|
description: description,
|
|
102
|
+
headers: headers.transform_values do |header|
|
|
103
|
+
header.to_openapi(version)
|
|
104
|
+
end.presence,
|
|
90
105
|
content: {
|
|
91
106
|
content_type => {
|
|
92
|
-
|
|
107
|
+
**if json_seq_type? && schema.array? && version >= OpenAPI::V3_2
|
|
108
|
+
{ itemSchema: schema.items.to_openapi(version) }
|
|
109
|
+
else
|
|
110
|
+
{ schema: schema.to_openapi(version) }
|
|
111
|
+
end,
|
|
93
112
|
examples: examples.transform_values(&:to_openapi).presence
|
|
94
113
|
}.compact
|
|
95
114
|
},
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
end.presence
|
|
99
|
-
links: links.transform_values(&:to_openapi).presence
|
|
115
|
+
links: links.transform_values do |link|
|
|
116
|
+
link.to_openapi(version)
|
|
117
|
+
end.presence
|
|
100
118
|
}
|
|
101
119
|
end
|
|
102
120
|
)
|
|
@@ -4,8 +4,16 @@ module Jsapi
|
|
|
4
4
|
module Meta
|
|
5
5
|
module Schema
|
|
6
6
|
class Discriminator < Model::Base
|
|
7
|
+
include OpenAPI::Extensions
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# :attr: default_mapping
|
|
11
|
+
# Applies to \OpenAPI 3.2 and higher.
|
|
12
|
+
attribute :default_mapping, String
|
|
13
|
+
|
|
7
14
|
##
|
|
8
15
|
# :attr: mappings
|
|
16
|
+
# Applies to \OpenAPI 3.0 and higher.
|
|
9
17
|
attribute :mappings, { Object => String }
|
|
10
18
|
|
|
11
19
|
##
|
|
@@ -15,12 +23,14 @@ module Jsapi
|
|
|
15
23
|
# Returns a hash representing the \OpenAPI discriminator object.
|
|
16
24
|
def to_openapi(version, *)
|
|
17
25
|
version = OpenAPI::Version.from(version)
|
|
18
|
-
return property_name if version
|
|
26
|
+
return property_name if version < OpenAPI::V3_0
|
|
19
27
|
|
|
20
|
-
{
|
|
28
|
+
result = {
|
|
21
29
|
propertyName: property_name,
|
|
22
|
-
mapping: mappings.transform_keys(&:to_s).presence
|
|
23
|
-
|
|
30
|
+
mapping: mappings.transform_keys(&:to_s).presence,
|
|
31
|
+
defaultMapping: (default_mapping if version >= OpenAPI::V3_2)
|
|
32
|
+
}
|
|
33
|
+
version >= OpenAPI::V3_1 ? with_openapi_extensions(result) : result.compact
|
|
24
34
|
end
|
|
25
35
|
end
|
|
26
36
|
end
|
|
@@ -57,17 +57,36 @@ module Jsapi
|
|
|
57
57
|
|
|
58
58
|
properties = resolve_properties(definitions, context: context)
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
discriminating_property = properties[discriminator.property_name]
|
|
61
|
+
if discriminating_property.nil?
|
|
62
|
+
raise InvalidValueError.new('discriminator property',
|
|
63
|
+
discriminator.property_name,
|
|
64
|
+
valid_values: properties.keys)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
discriminating_value = discriminating_property.reader.call(object)
|
|
68
|
+
if discriminating_value.nil?
|
|
69
|
+
discriminating_value = discriminating_property.default_value(
|
|
70
|
+
definitions,
|
|
71
|
+
context: context
|
|
72
|
+
)
|
|
73
|
+
if discriminating_value.nil? && discriminator.default_mapping.nil?
|
|
74
|
+
raise "discriminating value can't be nil"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
64
77
|
|
|
65
|
-
|
|
66
|
-
value = property.default_value(definitions, context: context) if value.nil?
|
|
67
|
-
raise "#{discriminator.property_name} can't be nil" if value.nil?
|
|
78
|
+
schema_name = discriminator.mapping(discriminating_value) || discriminating_value
|
|
68
79
|
|
|
69
|
-
schema = definitions.find_schema(
|
|
70
|
-
|
|
80
|
+
schema = definitions.find_schema(schema_name)
|
|
81
|
+
if schema.nil?
|
|
82
|
+
default_mapping = discriminator.default_mapping
|
|
83
|
+
schema = definitions.find_schema(default_mapping) unless default_mapping.nil?
|
|
84
|
+
|
|
85
|
+
if schema.nil?
|
|
86
|
+
raise "inheriting schema couldn't be found: " \
|
|
87
|
+
"#{[schema_name, default_mapping].compact.map(&:inspect).join(' or ')}"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
71
90
|
|
|
72
91
|
schema.resolve(definitions).resolve_schema(object, definitions, context: context)
|
|
73
92
|
end
|
|
@@ -43,7 +43,7 @@ module Jsapi
|
|
|
43
43
|
|
|
44
44
|
def to_openapi_validation(version)
|
|
45
45
|
version = OpenAPI::Version.from(version)
|
|
46
|
-
return to_json_schema_validation if version
|
|
46
|
+
return to_json_schema_validation if version >= OpenAPI::V3_1
|
|
47
47
|
return super unless exclusive
|
|
48
48
|
|
|
49
49
|
{ maximum: value, exclusiveMaximum: true }
|
|
@@ -43,7 +43,7 @@ module Jsapi
|
|
|
43
43
|
|
|
44
44
|
def to_openapi_validation(version)
|
|
45
45
|
version = OpenAPI::Version.from(version)
|
|
46
|
-
return to_json_schema_validation if version
|
|
46
|
+
return to_json_schema_validation if version >= OpenAPI::V3_1
|
|
47
47
|
return super unless exclusive
|
|
48
48
|
|
|
49
49
|
{ minimum: value, exclusiveMinimum: true }
|
|
@@ -24,12 +24,11 @@ module Jsapi
|
|
|
24
24
|
attribute :name, String
|
|
25
25
|
|
|
26
26
|
# Returns a hash representing the \OpenAPI security scheme object.
|
|
27
|
-
def to_openapi(*)
|
|
27
|
+
def to_openapi(version, *)
|
|
28
|
+
version = OpenAPI::Version.from(version)
|
|
29
|
+
|
|
28
30
|
with_openapi_extensions(
|
|
29
|
-
|
|
30
|
-
name: name,
|
|
31
|
-
in: self.in,
|
|
32
|
-
description: description
|
|
31
|
+
base_openapi_fields('apiKey', version).merge(name: name, in: self.in)
|
|
33
32
|
)
|
|
34
33
|
end
|
|
35
34
|
end
|