jsapi 1.2 → 1.3
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 +27 -10
- data/lib/jsapi/controller/response.rb +29 -5
- data/lib/jsapi/meta/callback/base.rb +1 -1
- data/lib/jsapi/meta/definitions.rb +10 -6
- 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 +46 -0
- data/lib/jsapi/meta/openapi/version.rb +6 -0
- data/lib/jsapi/meta/openapi.rb +2 -0
- data/lib/jsapi/meta/operation.rb +6 -14
- data/lib/jsapi/meta/parameter/base.rb +82 -59
- 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/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2abec73a53f67bfebe51e0466e662be1dfc393f3fe5946612a12c94fde8b463b
|
|
4
|
+
data.tar.gz: f9c69c6df40d4f88e5175beb185a528ad76f2c6b4cbf6a8f88ac15915943f706
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ca369ab50a38016fa37e9199e5a38f9248d2cbcfa51d80c39461dd206d8b09fb6ae60ea29861d211b9a939e408b6e48f35008da577c9f3a789bb6ebb592fafda
|
|
7
|
+
data.tar.gz: 8093446b1d7601d9a0e89cae395fa0ced837901b1a9eb0866ebcfd721cebb9e07d611c851735c847a699d71cec4ca474d04e39710ebc244476f6deb635e7fdc7
|
data/lib/jsapi/configuration.rb
CHANGED
|
@@ -4,11 +4,11 @@ module Jsapi
|
|
|
4
4
|
# Holds the \Jsapi configuration.
|
|
5
5
|
class Configuration
|
|
6
6
|
# The path where the API definitions are located relative to +Rails.root+.
|
|
7
|
-
# The default is <code>"
|
|
7
|
+
# The default is <code>"jsapi/api_defs"</code>.
|
|
8
8
|
attr_accessor :api_defs_path
|
|
9
9
|
|
|
10
10
|
def initialize # :nodoc:
|
|
11
|
-
@api_defs_path = '
|
|
11
|
+
@api_defs_path = 'jsapi/api_defs'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# Returns the absolute +Pathname+ for +args+ within +api_defs_path+.
|
|
@@ -15,7 +15,9 @@ module Jsapi
|
|
|
15
15
|
# Performs an API operation by calling the given block. The request parameters are
|
|
16
16
|
# passed as an instance of the operation's model class to the block. The object
|
|
17
17
|
# returned by the block is implicitly rendered according to the appropriate +response+
|
|
18
|
-
# specification when the content type is a JSON MIME type.
|
|
18
|
+
# specification when the content type is a JSON MIME type. When content type is
|
|
19
|
+
# <code>application/json-seq</code>, the object returned by the block is streamed in
|
|
20
|
+
# JSON sequence text format.
|
|
19
21
|
#
|
|
20
22
|
# api_operation('foo') do |api_params|
|
|
21
23
|
# # ...
|
|
@@ -153,18 +155,29 @@ module Jsapi
|
|
|
153
155
|
end
|
|
154
156
|
|
|
155
157
|
# Write response
|
|
156
|
-
return unless response_model.json_type?
|
|
158
|
+
return unless response_model.json_type? || response_model.json_seq_type?
|
|
157
159
|
|
|
158
160
|
response = Response.new(result, response_model, definitions, omit: omit)
|
|
159
161
|
self.content_type = response_model.content_type
|
|
160
|
-
|
|
162
|
+
|
|
163
|
+
if response_model.json_seq_type?
|
|
164
|
+
self.response.status = status
|
|
165
|
+
|
|
166
|
+
self.response.stream.tap do |stream|
|
|
167
|
+
response.write_json_seq_to(stream)
|
|
168
|
+
ensure
|
|
169
|
+
stream.close
|
|
170
|
+
end
|
|
171
|
+
else
|
|
172
|
+
render(json: response, status: status)
|
|
173
|
+
end
|
|
161
174
|
end
|
|
162
175
|
|
|
163
176
|
def _api_params(operation, definitions, strong:)
|
|
164
177
|
(operation.model || Model::Base).new(
|
|
165
178
|
Parameters.new(
|
|
166
179
|
params.except(:action, :controller, :format).permit!,
|
|
167
|
-
request
|
|
180
|
+
request,
|
|
168
181
|
operation,
|
|
169
182
|
definitions,
|
|
170
183
|
strong: strong
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'cgi'
|
|
4
|
+
|
|
3
5
|
module Jsapi
|
|
4
6
|
module Controller
|
|
5
7
|
# Used to wrap request parameters.
|
|
@@ -14,18 +16,32 @@ module Jsapi
|
|
|
14
16
|
# If +strong+ is true+ parameters that can be mapped are accepted only. That means that
|
|
15
17
|
# the instance created is invalid if +params+ contains any parameters that can't be
|
|
16
18
|
# mapped to a parameter or a request body property of +operation+.
|
|
17
|
-
def initialize(params,
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
def initialize(params, request, operation, definitions, strong: false)
|
|
20
|
+
params = params.to_h
|
|
21
|
+
unassigned_params = params.dup
|
|
22
|
+
|
|
23
|
+
@params_to_be_validated = strong == true ? params.dup : {}
|
|
20
24
|
@raw_attributes = {}
|
|
21
|
-
@raw_additional_attributes = {}
|
|
22
25
|
|
|
23
26
|
# Parameters
|
|
24
27
|
operation.parameters.each do |name, parameter_model|
|
|
25
28
|
parameter_model = parameter_model.resolve(definitions)
|
|
26
29
|
|
|
27
30
|
@raw_attributes[name] = JSON.wrap(
|
|
28
|
-
parameter_model.in
|
|
31
|
+
case parameter_model.in
|
|
32
|
+
when 'header'
|
|
33
|
+
request.headers[name]
|
|
34
|
+
when 'querystring'
|
|
35
|
+
query_params = request.query_parameters
|
|
36
|
+
keys = query_params.keys
|
|
37
|
+
|
|
38
|
+
unassigned_params.except!(*keys)
|
|
39
|
+
@params_to_be_validated.except!(*keys)
|
|
40
|
+
|
|
41
|
+
parameter_model.object? ? params.slice(*keys) : query_params.to_query
|
|
42
|
+
else
|
|
43
|
+
unassigned_params.delete(name)
|
|
44
|
+
end,
|
|
29
45
|
parameter_model.schema.resolve(definitions),
|
|
30
46
|
definitions,
|
|
31
47
|
context: :request
|
|
@@ -37,23 +53,24 @@ module Jsapi
|
|
|
37
53
|
&.schema&.resolve(definitions)
|
|
38
54
|
if request_body_schema&.object?
|
|
39
55
|
request_body = JSON.wrap(
|
|
40
|
-
|
|
56
|
+
unassigned_params,
|
|
41
57
|
request_body_schema,
|
|
42
58
|
definitions,
|
|
43
59
|
context: :request
|
|
44
60
|
)
|
|
45
61
|
@raw_attributes.merge!(request_body.raw_attributes)
|
|
46
62
|
@raw_additional_attributes = request_body.raw_additional_attributes
|
|
63
|
+
@params_to_be_validated.except!(*@raw_additional_attributes.keys)
|
|
64
|
+
else
|
|
65
|
+
@raw_additional_attributes = {}
|
|
47
66
|
end
|
|
48
67
|
end
|
|
49
68
|
|
|
50
69
|
# Validates the request parameters. Returns true if the parameters are valid, false
|
|
51
70
|
# otherwise. Detected errors are added to +errors+.
|
|
52
71
|
def validate(errors)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
!@strong || validate_parameters(@params, attributes, errors)
|
|
56
|
-
].all?
|
|
72
|
+
validate_attributes(errors) &&
|
|
73
|
+
validate_parameters(@params_to_be_validated, attributes, errors)
|
|
57
74
|
end
|
|
58
75
|
|
|
59
76
|
private
|
|
@@ -50,11 +50,27 @@ module Jsapi
|
|
|
50
50
|
# Returns the \JSON representation of the response as a string.
|
|
51
51
|
def to_json(*)
|
|
52
52
|
schema = @response.schema.resolve(@definitions)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
with_locale { jsonify(@object, schema) }.to_json
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Writes the response in \JSON sequence text format to +stream+.
|
|
57
|
+
def write_json_seq_to(stream)
|
|
58
|
+
schema = @response.schema.resolve(@definitions)
|
|
59
|
+
with_locale do
|
|
60
|
+
items, item_schema =
|
|
61
|
+
if schema.array? && @object.respond_to?(:each)
|
|
62
|
+
[@object, schema.items.resolve(@definitions)]
|
|
63
|
+
else
|
|
64
|
+
[[@object], schema]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
items.each do |item|
|
|
68
|
+
stream.write("\u001E") # Record separator (see RFC 7464)
|
|
69
|
+
stream.write(jsonify(item, item_schema).to_json)
|
|
70
|
+
stream.write("\n")
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
nil
|
|
58
74
|
end
|
|
59
75
|
|
|
60
76
|
private
|
|
@@ -138,6 +154,14 @@ module Jsapi
|
|
|
138
154
|
|
|
139
155
|
properties.presence
|
|
140
156
|
end
|
|
157
|
+
|
|
158
|
+
def with_locale(&block)
|
|
159
|
+
if @response.locale
|
|
160
|
+
I18n.with_locale(@response.locale, &block)
|
|
161
|
+
else
|
|
162
|
+
yield
|
|
163
|
+
end
|
|
164
|
+
end
|
|
141
165
|
end
|
|
142
166
|
end
|
|
143
167
|
end
|
|
@@ -23,7 +23,7 @@ module Jsapi
|
|
|
23
23
|
# Returns a hash representing the \OpenAPI callback object.
|
|
24
24
|
def to_openapi(version, definitions)
|
|
25
25
|
operations.transform_values do |operation|
|
|
26
|
-
|
|
26
|
+
OpenAPI::PathItem.new([operation]).to_openapi(version, definitions)
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
end
|
|
@@ -231,9 +231,7 @@ module Jsapi
|
|
|
231
231
|
openapi_paths =
|
|
232
232
|
operations.group_by { |operation| operation.path || default_operation_path }
|
|
233
233
|
.transform_values do |operations_by_path|
|
|
234
|
-
|
|
235
|
-
operation.to_openapi(version, self)
|
|
236
|
-
end
|
|
234
|
+
OpenAPI::PathItem.new(operations_by_path).to_openapi(version, self)
|
|
237
235
|
end.presence
|
|
238
236
|
|
|
239
237
|
openapi_objects =
|
|
@@ -271,10 +269,16 @@ module Jsapi
|
|
|
271
269
|
else
|
|
272
270
|
{
|
|
273
271
|
# Order according to the OpenAPI specification 3.x
|
|
274
|
-
openapi:
|
|
272
|
+
openapi:
|
|
273
|
+
case version.minor
|
|
274
|
+
when 0 then '3.0.3'
|
|
275
|
+
when 1 then '3.1.1'
|
|
276
|
+
when 2 then '3.2.0'
|
|
277
|
+
end,
|
|
275
278
|
info: openapi_objects[:info],
|
|
276
|
-
servers:
|
|
277
|
-
[
|
|
279
|
+
servers:
|
|
280
|
+
openapi_objects[:servers] ||
|
|
281
|
+
[default_server&.to_openapi(version)].compact.presence,
|
|
278
282
|
paths: openapi_paths,
|
|
279
283
|
components: {
|
|
280
284
|
schemas: openapi_objects[:schemas],
|
|
@@ -29,13 +29,11 @@ module Jsapi
|
|
|
29
29
|
|
|
30
30
|
# Returns a hash representing the \OpenAPI example object.
|
|
31
31
|
def to_openapi(*)
|
|
32
|
-
with_openapi_extensions(
|
|
33
|
-
|
|
34
|
-
result[:
|
|
35
|
-
else
|
|
36
|
-
result[:value] = value
|
|
32
|
+
with_openapi_extensions(
|
|
33
|
+
{ summary: summary, description: description }.tap do |result|
|
|
34
|
+
result[external? ? :externalValue : :value] = value
|
|
37
35
|
end
|
|
38
|
-
|
|
36
|
+
)
|
|
39
37
|
end
|
|
40
38
|
end
|
|
41
39
|
end
|
data/lib/jsapi/meta/link/base.rb
CHANGED
|
@@ -33,13 +33,15 @@ module Jsapi
|
|
|
33
33
|
attribute :server, Server
|
|
34
34
|
|
|
35
35
|
# Returns a hash representing the \OpenAPI link object.
|
|
36
|
-
def to_openapi(*)
|
|
36
|
+
def to_openapi(version, *)
|
|
37
|
+
version = OpenAPI::Version.from(version)
|
|
38
|
+
|
|
37
39
|
with_openapi_extensions(
|
|
38
40
|
operationId: operation_id,
|
|
39
41
|
parameters: parameters.presence,
|
|
40
42
|
requestBody: request_body,
|
|
41
43
|
description: description,
|
|
42
|
-
server: server&.to_openapi
|
|
44
|
+
server: server&.to_openapi(version)
|
|
43
45
|
)
|
|
44
46
|
end
|
|
45
47
|
end
|
|
@@ -18,12 +18,20 @@ module Jsapi
|
|
|
18
18
|
# The authorization URL to be used for the flow.
|
|
19
19
|
attribute :authorization_url, String
|
|
20
20
|
|
|
21
|
+
##
|
|
22
|
+
# :attr: device_authorization_url
|
|
23
|
+
# The device authorization URL to be used for the flow.
|
|
24
|
+
#
|
|
25
|
+
# Note that the device authorization URL was introduced with \OpenAPI 3.2.
|
|
26
|
+
# It is omitted when generating an \OpenAPI document with a lower version.
|
|
27
|
+
attribute :device_authorization_url, String
|
|
28
|
+
|
|
21
29
|
##
|
|
22
30
|
# :attr: refresh_url
|
|
23
31
|
# The refresh URL to be used for the flow.
|
|
24
32
|
#
|
|
25
33
|
# Note that the refresh URL was introduced with \OpenAPI 3.0. It is
|
|
26
|
-
#
|
|
34
|
+
# omitted when generating an \OpenAPI document with a lower version.
|
|
27
35
|
attribute :refresh_url, String
|
|
28
36
|
|
|
29
37
|
##
|
|
@@ -42,8 +50,9 @@ module Jsapi
|
|
|
42
50
|
|
|
43
51
|
with_openapi_extensions(
|
|
44
52
|
authorizationUrl: authorization_url,
|
|
53
|
+
deviceAuthorizationUrl: (device_authorization_url if version >= OpenAPI::V3_2),
|
|
45
54
|
tokenUrl: token_url,
|
|
46
|
-
refreshUrl: (refresh_url if version
|
|
55
|
+
refreshUrl: (refresh_url if version >= OpenAPI::V3_0),
|
|
47
56
|
scopes: scopes.transform_values(&:description)
|
|
48
57
|
)
|
|
49
58
|
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jsapi
|
|
4
|
+
module Meta
|
|
5
|
+
module OpenAPI
|
|
6
|
+
class PathItem # :nodoc:
|
|
7
|
+
def initialize(operations)
|
|
8
|
+
@operations = operations
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_openapi(version, definitions)
|
|
12
|
+
version = OpenAPI::Version.from(version)
|
|
13
|
+
|
|
14
|
+
{}.tap do |fields|
|
|
15
|
+
@operations.each do |operation|
|
|
16
|
+
method = operation.method
|
|
17
|
+
standardized_method = method.downcase
|
|
18
|
+
|
|
19
|
+
if standard_method?(standardized_method, version)
|
|
20
|
+
fields[standardized_method] = operation.to_openapi(version, definitions)
|
|
21
|
+
elsif version >= OpenAPI::V3_2
|
|
22
|
+
additional_operations = fields[:additionalOperations] ||= {}
|
|
23
|
+
additional_operations[method] = operation.to_openapi(version, definitions)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def standard_method?(method, version)
|
|
32
|
+
case method
|
|
33
|
+
when 'delete', 'get', 'head', 'options', 'patch', 'post', 'put'
|
|
34
|
+
true
|
|
35
|
+
when 'trace'
|
|
36
|
+
version >= OpenAPI::V3_0
|
|
37
|
+
when 'query'
|
|
38
|
+
version >= OpenAPI::V3_2
|
|
39
|
+
else
|
|
40
|
+
false
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -19,6 +19,8 @@ module Jsapi
|
|
|
19
19
|
new(3, 0)
|
|
20
20
|
when '3.1'
|
|
21
21
|
new(3, 1)
|
|
22
|
+
when '3.2'
|
|
23
|
+
new(3, 2)
|
|
22
24
|
else
|
|
23
25
|
raise ArgumentError, "unsupported OpenAPI version: #{version.inspect}"
|
|
24
26
|
end
|
|
@@ -46,6 +48,10 @@ module Jsapi
|
|
|
46
48
|
minor <=> other.minor
|
|
47
49
|
end
|
|
48
50
|
|
|
51
|
+
def inspect
|
|
52
|
+
"<#{self.class.name} #{self}>"
|
|
53
|
+
end
|
|
54
|
+
|
|
49
55
|
def to_s # :nodoc:
|
|
50
56
|
"#{major}.#{minor}"
|
|
51
57
|
end
|
data/lib/jsapi/meta/openapi.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative 'openapi/extensions'
|
|
4
4
|
require_relative 'openapi/version'
|
|
5
|
+
require_relative 'openapi/path_item'
|
|
5
6
|
|
|
6
7
|
module Jsapi
|
|
7
8
|
module Meta
|
|
@@ -9,6 +10,7 @@ module Jsapi
|
|
|
9
10
|
V2_0 = Version.new(2, 0)
|
|
10
11
|
V3_0 = Version.new(3, 0)
|
|
11
12
|
V3_1 = Version.new(3, 1)
|
|
13
|
+
V3_2 = Version.new(3, 2)
|
|
12
14
|
end
|
|
13
15
|
end
|
|
14
16
|
end
|
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
|
|
@@ -97,7 +87,7 @@ module Jsapi
|
|
|
97
87
|
|
|
98
88
|
##
|
|
99
89
|
# :attr: summary
|
|
100
|
-
# The short
|
|
90
|
+
# The short description of the operation.
|
|
101
91
|
attribute :summary, String
|
|
102
92
|
|
|
103
93
|
##
|
|
@@ -148,7 +138,9 @@ module Jsapi
|
|
|
148
138
|
end
|
|
149
139
|
result[:schemes] = schemes if schemes.present?
|
|
150
140
|
elsif servers.present?
|
|
151
|
-
result[:servers] = servers.map
|
|
141
|
+
result[:servers] = servers.map do |server|
|
|
142
|
+
server.to_openapi(version)
|
|
143
|
+
end
|
|
152
144
|
end
|
|
153
145
|
# Parameters (and request body)
|
|
154
146
|
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
|
|
@@ -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
|
|
@@ -8,6 +8,22 @@ module Jsapi
|
|
|
8
8
|
# :attr: description
|
|
9
9
|
# The description of the security scheme.
|
|
10
10
|
attribute :description, String
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# :attr: deprecated
|
|
14
|
+
# Specifies whether or not the security scheme is deprecated.
|
|
15
|
+
# Applies to \OpenAPI 3.2 and higher.
|
|
16
|
+
attribute :deprecated, values: [true, false]
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def base_openapi_fields(type, version)
|
|
21
|
+
{
|
|
22
|
+
type: type,
|
|
23
|
+
description: description,
|
|
24
|
+
deprecated: (deprecated?.presence if version >= OpenAPI::V3_2)
|
|
25
|
+
}
|
|
26
|
+
end
|
|
11
27
|
end
|
|
12
28
|
end
|
|
13
29
|
end
|
|
@@ -13,17 +13,10 @@ module Jsapi
|
|
|
13
13
|
version = OpenAPI::Version.from(version)
|
|
14
14
|
|
|
15
15
|
with_openapi_extensions(
|
|
16
|
-
if version
|
|
17
|
-
|
|
18
|
-
type: 'basic',
|
|
19
|
-
description: description
|
|
20
|
-
}
|
|
16
|
+
if version < OpenAPI::V3_0
|
|
17
|
+
base_openapi_fields('basic', version)
|
|
21
18
|
else
|
|
22
|
-
|
|
23
|
-
type: 'http',
|
|
24
|
-
scheme: 'basic',
|
|
25
|
-
description: description
|
|
26
|
-
}
|
|
19
|
+
base_openapi_fields('http', version).merge(scheme: 'basic')
|
|
27
20
|
end
|
|
28
21
|
)
|
|
29
22
|
end
|
|
@@ -7,7 +7,7 @@ module Jsapi
|
|
|
7
7
|
# Specifies a security scheme based on bearer authentication.
|
|
8
8
|
#
|
|
9
9
|
# Note that Bearer authentication was introduced with \OpenAPI 3.0. Thus, a security
|
|
10
|
-
# scheme of this class is
|
|
10
|
+
# scheme of this class is omitted when generating an \OpenAPI 2.0 document.
|
|
11
11
|
class Bearer < Base
|
|
12
12
|
include OpenAPI::Extensions
|
|
13
13
|
|
|
@@ -16,17 +16,17 @@ module Jsapi
|
|
|
16
16
|
# The format of the bearer token.
|
|
17
17
|
attribute :bearer_format, String
|
|
18
18
|
|
|
19
|
-
# Returns a hash representing the \OpenAPI security scheme object, or
|
|
20
|
-
#
|
|
19
|
+
# Returns a hash representing the \OpenAPI security scheme object, or +nil+
|
|
20
|
+
# if <code>version</code> is less than \OpenAPI 3.0.
|
|
21
21
|
def to_openapi(version, *)
|
|
22
22
|
version = OpenAPI::Version.from(version)
|
|
23
|
-
return if version
|
|
23
|
+
return if version < OpenAPI::V3_0
|
|
24
24
|
|
|
25
25
|
with_openapi_extensions(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
base_openapi_fields('http', version).merge(
|
|
27
|
+
scheme: 'bearer',
|
|
28
|
+
bearerFormat: bearer_format
|
|
29
|
+
)
|
|
30
30
|
)
|
|
31
31
|
end
|
|
32
32
|
end
|
|
@@ -18,15 +18,13 @@ module Jsapi
|
|
|
18
18
|
attribute :scheme, String
|
|
19
19
|
|
|
20
20
|
# Returns a hash representing the \OpenAPI security scheme object, or +nil+
|
|
21
|
-
# if <code>version
|
|
21
|
+
# if <code>version</code> is less than \OpenAPI 3.0.
|
|
22
22
|
def to_openapi(version, *)
|
|
23
23
|
version = OpenAPI::Version.from(version)
|
|
24
|
-
return if version
|
|
24
|
+
return if version < OpenAPI::V3_0
|
|
25
25
|
|
|
26
26
|
with_openapi_extensions(
|
|
27
|
-
|
|
28
|
-
scheme: scheme,
|
|
29
|
-
description: description
|
|
27
|
+
base_openapi_fields('http', version).merge(scheme: scheme)
|
|
30
28
|
)
|
|
31
29
|
end
|
|
32
30
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jsapi
|
|
4
|
+
module Meta
|
|
5
|
+
module SecurityScheme
|
|
6
|
+
# Specifies a security scheme based on MutualTLS.
|
|
7
|
+
class MutualTLS < Base
|
|
8
|
+
include OpenAPI::Extensions
|
|
9
|
+
|
|
10
|
+
# Returns a hash representing the \OpenAPI security scheme object, or +nil+
|
|
11
|
+
# if <code>version</code> is less than \OpenAPI 3.1.
|
|
12
|
+
def to_openapi(version, *)
|
|
13
|
+
version = OpenAPI::Version.from(version)
|
|
14
|
+
return if version < OpenAPI::V3_1
|
|
15
|
+
|
|
16
|
+
with_openapi_extensions(
|
|
17
|
+
base_openapi_fields('mutualTLS', version)
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -9,34 +9,50 @@ module Jsapi
|
|
|
9
9
|
|
|
10
10
|
##
|
|
11
11
|
# :attr: oauth_flows
|
|
12
|
-
#
|
|
12
|
+
# Maps one or more of the following keys to OAuthFlow objects.
|
|
13
13
|
#
|
|
14
14
|
# - <code>"authorization_code"</code>
|
|
15
15
|
# - <code>"client_credentials"</code>
|
|
16
|
+
# - <code>"device_authorization"</code>
|
|
16
17
|
# - <code>"implicit"</code>
|
|
17
18
|
# - <code>"password"</code>
|
|
18
19
|
#
|
|
19
|
-
#
|
|
20
|
+
# Note that <code>"device_authorization"</code> was introduced with \OpenAPI 3.2.
|
|
21
|
+
# This entry is omitted when generating an \OpenAPI document with a lower version.
|
|
20
22
|
attribute :oauth_flows, { String => OAuthFlow },
|
|
21
|
-
keys: %w[authorization_code
|
|
23
|
+
keys: %w[authorization_code
|
|
24
|
+
client_credentials
|
|
25
|
+
device_authorization
|
|
26
|
+
implicit
|
|
27
|
+
password]
|
|
28
|
+
##
|
|
29
|
+
# :attr: oauth2_metadata_url
|
|
30
|
+
# The URL of the OAuth2 authorization server metadata.
|
|
31
|
+
# Applies to \OpenAPI 3.2 and higher.
|
|
32
|
+
attribute :oauth2_metadata_url, String
|
|
22
33
|
|
|
23
34
|
# Returns a hash representing the \OpenAPI security scheme object.
|
|
24
35
|
def to_openapi(version, *)
|
|
25
36
|
version = OpenAPI::Version.from(version)
|
|
26
37
|
|
|
27
|
-
with_openapi_extensions(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
h[:flows] = oauth_flows.to_h do |key, value|
|
|
38
|
+
with_openapi_extensions(
|
|
39
|
+
base_openapi_fields('oauth2', version).tap do |fields|
|
|
40
|
+
flows = oauth_flows
|
|
41
|
+
flows = flows.except('device_authorization') unless version >= OpenAPI::V3_2
|
|
42
|
+
|
|
43
|
+
if version >= OpenAPI::V3_0
|
|
44
|
+
fields[:flows] = flows.to_h do |key, value|
|
|
35
45
|
[key.to_s.camelize(:lower).to_sym, value.to_openapi(version)]
|
|
36
|
-
end
|
|
46
|
+
end if flows.any?
|
|
47
|
+
|
|
48
|
+
fields[:oauth2MetadataUrl] = oauth2_metadata_url if version >= OpenAPI::V3_2
|
|
49
|
+
elsif flows.one?
|
|
50
|
+
key, flow = flows.first
|
|
51
|
+
fields[:flow] = key.to_s
|
|
52
|
+
fields.merge!(flow.to_openapi(version))
|
|
37
53
|
end
|
|
38
54
|
end
|
|
39
|
-
|
|
55
|
+
)
|
|
40
56
|
end
|
|
41
57
|
end
|
|
42
58
|
end
|
|
@@ -4,9 +4,6 @@ module Jsapi
|
|
|
4
4
|
module Meta
|
|
5
5
|
module SecurityScheme
|
|
6
6
|
# Specifies a security scheme based on OpenID Connect.
|
|
7
|
-
#
|
|
8
|
-
# OpenID Connect was introduced with \OpenAPI 3.0. Thus, a security scheme of
|
|
9
|
-
# this class is skipped when generating an \OpenAPI 2.0 document.
|
|
10
7
|
class OpenIDConnect < Base
|
|
11
8
|
include OpenAPI::Extensions
|
|
12
9
|
|
|
@@ -15,15 +12,15 @@ module Jsapi
|
|
|
15
12
|
attribute :open_id_connect_url, String
|
|
16
13
|
|
|
17
14
|
# Returns a hash representing the \OpenAPI security scheme object, or +nil+
|
|
18
|
-
# if <code>version
|
|
15
|
+
# if <code>version</code> is less than \OpenAPI 3.0.
|
|
19
16
|
def to_openapi(version, *)
|
|
20
17
|
version = OpenAPI::Version.from(version)
|
|
21
|
-
return if version
|
|
18
|
+
return if version < OpenAPI::V3_0
|
|
22
19
|
|
|
23
20
|
with_openapi_extensions(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
base_openapi_fields('openIdConnect', version).merge(
|
|
22
|
+
openIdConnectUrl: open_id_connect_url
|
|
23
|
+
)
|
|
27
24
|
)
|
|
28
25
|
end
|
|
29
26
|
end
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative 'security_scheme/base'
|
|
4
4
|
require_relative 'security_scheme/api_key'
|
|
5
5
|
require_relative 'security_scheme/http'
|
|
6
|
+
require_relative 'security_scheme/mutual_tls'
|
|
6
7
|
require_relative 'security_scheme/oauth2'
|
|
7
8
|
require_relative 'security_scheme/open_id_connect'
|
|
8
9
|
|
|
@@ -31,6 +32,8 @@ module Jsapi
|
|
|
31
32
|
HTTP.new(keywords.merge(scheme: 'basic'))
|
|
32
33
|
when 'http' # OpenAPI 3.0 and higher
|
|
33
34
|
HTTP.new(keywords)
|
|
35
|
+
when 'mutual_tls' # OpenAPI 3.1 and higher
|
|
36
|
+
MutualTLS.new(keywords)
|
|
34
37
|
when 'oauth2'
|
|
35
38
|
OAuth2.new(keywords)
|
|
36
39
|
when 'open_id_connect' # OpenAPI 3.0 and higher
|
data/lib/jsapi/meta/server.rb
CHANGED
|
@@ -11,6 +11,11 @@ module Jsapi
|
|
|
11
11
|
# The description of the server.
|
|
12
12
|
attribute :description, String
|
|
13
13
|
|
|
14
|
+
##
|
|
15
|
+
# :attr: name
|
|
16
|
+
# The optional unique name of the server. Applies to \OpenAPI 3.2 and higher.
|
|
17
|
+
attribute :name, String
|
|
18
|
+
|
|
14
19
|
##
|
|
15
20
|
# :attr: url
|
|
16
21
|
# The absolute or relative URL of the server.
|
|
@@ -22,10 +27,13 @@ module Jsapi
|
|
|
22
27
|
attribute :variables, { String => ServerVariable }
|
|
23
28
|
|
|
24
29
|
# Returns a hash representing the \OpenAPI server object.
|
|
25
|
-
def to_openapi(*)
|
|
30
|
+
def to_openapi(version, *)
|
|
31
|
+
version = OpenAPI::Version.from(version)
|
|
32
|
+
|
|
26
33
|
with_openapi_extensions(
|
|
27
34
|
url: url,
|
|
28
35
|
description: description,
|
|
36
|
+
name: (name if version >= OpenAPI::V3_2),
|
|
29
37
|
variables: variables.transform_values(&:to_openapi).presence
|
|
30
38
|
)
|
|
31
39
|
end
|
data/lib/jsapi/meta/tag.rb
CHANGED
|
@@ -16,17 +16,47 @@ module Jsapi
|
|
|
16
16
|
# The ExternalDocumentation object.
|
|
17
17
|
attribute :external_docs, ExternalDocumentation
|
|
18
18
|
|
|
19
|
+
##
|
|
20
|
+
# :attr: kind
|
|
21
|
+
# The category of the tag. Applies to \OpenAPI 3.2 and higher.
|
|
22
|
+
attribute :kind, String
|
|
23
|
+
|
|
19
24
|
##
|
|
20
25
|
# :attr: name
|
|
21
26
|
# The name of the tag.
|
|
22
27
|
attribute :name, String
|
|
23
28
|
|
|
29
|
+
##
|
|
30
|
+
# :attr: parent
|
|
31
|
+
# The name of the parent tag. Applies to \OpenAPI 3.2 and higher.
|
|
32
|
+
attribute :parent, String
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
# :attr: summary
|
|
36
|
+
# The short summary of the tag. Applies to \OpenAPI 3.2 and higher.
|
|
37
|
+
attribute :summary, String
|
|
38
|
+
|
|
24
39
|
# Returns a hash representing the \OpenAPI tag object.
|
|
25
|
-
def to_openapi(*)
|
|
40
|
+
def to_openapi(version, *)
|
|
41
|
+
version = OpenAPI::Version.from(version)
|
|
42
|
+
|
|
26
43
|
with_openapi_extensions(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
44
|
+
if version >= OpenAPI::V3_2
|
|
45
|
+
{
|
|
46
|
+
name: name,
|
|
47
|
+
summary: summary,
|
|
48
|
+
description: description,
|
|
49
|
+
externalDocs: external_docs&.to_openapi,
|
|
50
|
+
parent: parent,
|
|
51
|
+
kind: kind
|
|
52
|
+
}
|
|
53
|
+
else
|
|
54
|
+
{
|
|
55
|
+
name: name,
|
|
56
|
+
description: description,
|
|
57
|
+
externalDocs: external_docs&.to_openapi
|
|
58
|
+
}
|
|
59
|
+
end
|
|
30
60
|
)
|
|
31
61
|
end
|
|
32
62
|
end
|
data/lib/jsapi/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jsapi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: '1.
|
|
4
|
+
version: '1.3'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Denis Göller
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description:
|
|
14
14
|
email: denis@dmgoeller.de
|
|
@@ -80,6 +80,7 @@ files:
|
|
|
80
80
|
- lib/jsapi/meta/oauth_flow.rb
|
|
81
81
|
- lib/jsapi/meta/openapi.rb
|
|
82
82
|
- lib/jsapi/meta/openapi/extensions.rb
|
|
83
|
+
- lib/jsapi/meta/openapi/path_item.rb
|
|
83
84
|
- lib/jsapi/meta/openapi/version.rb
|
|
84
85
|
- lib/jsapi/meta/operation.rb
|
|
85
86
|
- lib/jsapi/meta/parameter.rb
|
|
@@ -128,6 +129,7 @@ files:
|
|
|
128
129
|
- lib/jsapi/meta/security_scheme/http/basic.rb
|
|
129
130
|
- lib/jsapi/meta/security_scheme/http/bearer.rb
|
|
130
131
|
- lib/jsapi/meta/security_scheme/http/other.rb
|
|
132
|
+
- lib/jsapi/meta/security_scheme/mutual_tls.rb
|
|
131
133
|
- lib/jsapi/meta/security_scheme/oauth2.rb
|
|
132
134
|
- lib/jsapi/meta/security_scheme/open_id_connect.rb
|
|
133
135
|
- lib/jsapi/meta/server.rb
|