jsapi 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/jsapi/controller/methods.rb +4 -3
- data/lib/jsapi/controller/parameters.rb +2 -5
- data/lib/jsapi/controller/response.rb +46 -24
- data/lib/jsapi/json/object.rb +5 -8
- data/lib/jsapi/meta/example/model.rb +3 -4
- data/lib/jsapi/meta/openapi/contact.rb +3 -5
- data/lib/jsapi/meta/openapi/extensions.rb +31 -0
- data/lib/jsapi/meta/openapi/external_documentation.rb +3 -4
- data/lib/jsapi/meta/openapi/info.rb +4 -2
- data/lib/jsapi/meta/openapi/license.rb +3 -4
- data/lib/jsapi/meta/openapi/link/model.rb +4 -2
- data/lib/jsapi/meta/openapi/oauth_flow.rb +4 -2
- data/lib/jsapi/meta/openapi/root.rb +36 -32
- data/lib/jsapi/meta/openapi/security_scheme/api_key.rb +4 -2
- data/lib/jsapi/meta/openapi/security_scheme/http/basic.rb +17 -12
- data/lib/jsapi/meta/openapi/security_scheme/http/bearer.rb +4 -2
- data/lib/jsapi/meta/openapi/security_scheme/http/other.rb +4 -2
- data/lib/jsapi/meta/openapi/security_scheme/oauth2.rb +5 -5
- data/lib/jsapi/meta/openapi/security_scheme/open_id_connect.rb +4 -2
- data/lib/jsapi/meta/openapi/server.rb +4 -2
- data/lib/jsapi/meta/openapi/server_variable.rb +4 -2
- data/lib/jsapi/meta/openapi/tag.rb +4 -2
- data/lib/jsapi/meta/openapi.rb +1 -0
- data/lib/jsapi/meta/operation.rb +6 -3
- data/lib/jsapi/meta/parameter/model.rb +53 -47
- data/lib/jsapi/meta/request_body/model.rb +5 -3
- data/lib/jsapi/meta/response/model.rb +27 -22
- data/lib/jsapi/meta/schema/additional_properties.rb +29 -0
- data/lib/jsapi/meta/schema/base.rb +34 -29
- data/lib/jsapi/meta/schema/object.rb +9 -1
- data/lib/jsapi/meta/schema.rb +2 -1
- 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: 78a92c9f73f4a39ede65ad5b0b5646db67dc8b9e2b3ca444b6de32fdb75e349a
|
4
|
+
data.tar.gz: e235535541854c172f578cce7cf112ceebe880971643cb33125a76cc61bbd88a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c139744bacb90f772bb40779a8d149daf025dd838ffc3268c35640dfe18da1934e62ffd2e319658478ef5c4d54a4f630ed76eabf60a22df641f1ce7da218150
|
7
|
+
data.tar.gz: b9e72517dea9061eaa23b5ff5631745a18769614c04d2a91ae97db2e715c30504bc5b849fdcaa89384f7fb2618e5ea639601f637b9583b5fec219bd053006f08
|
@@ -13,9 +13,9 @@ module Jsapi
|
|
13
13
|
end
|
14
14
|
|
15
15
|
# Performs an API operation by calling the given block. The request parameters are
|
16
|
-
# passed as an instance of the operation's model class to the block.
|
17
|
-
# returned by the block is implicitly rendered
|
18
|
-
# +response+ specification.
|
16
|
+
# passed as an instance of the operation's model class to the block. Parameter names
|
17
|
+
# are converted to snake case. The object returned by the block is implicitly rendered
|
18
|
+
# according to the appropriate +response+ specification.
|
19
19
|
#
|
20
20
|
# api_operation('foo') do |api_params|
|
21
21
|
# # ...
|
@@ -53,6 +53,7 @@ module Jsapi
|
|
53
53
|
end
|
54
54
|
|
55
55
|
# Returns the request parameters as an instance of the operation's model class.
|
56
|
+
# Parameter names are converted to snake case.
|
56
57
|
#
|
57
58
|
# params = api_params('foo')
|
58
59
|
#
|
@@ -25,15 +25,12 @@ module Jsapi
|
|
25
25
|
end
|
26
26
|
request_body = operation.request_body&.resolve(definitions)
|
27
27
|
if request_body && request_body.schema.respond_to?(:properties)
|
28
|
-
meta_models.merge!(
|
29
|
-
request_body.schema.resolve_properties(:write, definitions)
|
30
|
-
)
|
28
|
+
meta_models.merge!(request_body.schema.resolve_properties(:write, definitions))
|
31
29
|
end
|
32
30
|
|
33
31
|
# Wrap params
|
34
32
|
meta_models.each do |name, meta_model|
|
35
|
-
@raw_attributes[name] =
|
36
|
-
JSON.wrap(params[name], meta_model.schema, definitions)
|
33
|
+
@raw_attributes[name.underscore] = JSON.wrap(params[name], meta_model.schema, definitions)
|
37
34
|
end
|
38
35
|
end
|
39
36
|
|
@@ -5,8 +5,8 @@ module Jsapi
|
|
5
5
|
# Used to serialize a response.
|
6
6
|
class Response
|
7
7
|
|
8
|
-
# Creates a new instance to serialize +object+ according to +response+. References
|
9
|
-
# resolved to API components in +definitions+.
|
8
|
+
# Creates a new instance to serialize +object+ according to +response+. References
|
9
|
+
# are resolved to API components in +definitions+.
|
10
10
|
def initialize(object, response, definitions)
|
11
11
|
@object = object
|
12
12
|
@response = response
|
@@ -37,33 +37,13 @@ module Jsapi
|
|
37
37
|
|
38
38
|
case schema.type
|
39
39
|
when 'array'
|
40
|
-
|
41
|
-
Array(object).map { |item| serialize(item, item_schema, path) }
|
40
|
+
serialize_array(object, schema, path)
|
42
41
|
when 'integer'
|
43
42
|
schema.convert(object.to_i)
|
44
43
|
when 'number'
|
45
44
|
schema.convert(object.to_f)
|
46
45
|
when 'object'
|
47
|
-
|
48
|
-
|
49
|
-
# Select inherriting schema on polymorphism
|
50
|
-
if (discriminator = schema.discriminator)
|
51
|
-
discriminator_property = schema.properties[discriminator.property_name]
|
52
|
-
schema = discriminator.resolve(
|
53
|
-
object.public_send(
|
54
|
-
discriminator_property.source || discriminator_property.name
|
55
|
-
),
|
56
|
-
@definitions
|
57
|
-
)
|
58
|
-
end
|
59
|
-
# Serialize properties
|
60
|
-
schema.resolve_properties(:read, @definitions).transform_values do |property|
|
61
|
-
serialize(
|
62
|
-
object.public_send(property.source || property.name),
|
63
|
-
property.schema.resolve(@definitions),
|
64
|
-
path.nil? ? property.name : "#{path}.#{property.name}"
|
65
|
-
)
|
66
|
-
end
|
46
|
+
serialize_object(object, schema, path)
|
67
47
|
when 'string'
|
68
48
|
schema.convert(
|
69
49
|
case schema.format
|
@@ -81,6 +61,48 @@ module Jsapi
|
|
81
61
|
object
|
82
62
|
end
|
83
63
|
end
|
64
|
+
|
65
|
+
def serialize_array(array, schema, path)
|
66
|
+
item_schema = schema.items.resolve(@definitions)
|
67
|
+
Array(array).map { |item| serialize(item, item_schema, path) }
|
68
|
+
end
|
69
|
+
|
70
|
+
def serialize_object(object, schema, path)
|
71
|
+
return if object.blank? # {}
|
72
|
+
|
73
|
+
# Select inherriting schema on polymorphism
|
74
|
+
if (discriminator = schema.discriminator)
|
75
|
+
discriminator_property = schema.properties[discriminator.property_name]
|
76
|
+
schema = discriminator.resolve(
|
77
|
+
object.public_send(discriminator_property.source || discriminator_property.name.underscore),
|
78
|
+
@definitions
|
79
|
+
)
|
80
|
+
end
|
81
|
+
# Serialize properties
|
82
|
+
properties = schema.resolve_properties(:read, @definitions).transform_values do |property|
|
83
|
+
serialize(
|
84
|
+
object.public_send(property.source || property.name.underscore),
|
85
|
+
property.schema.resolve(@definitions),
|
86
|
+
path.nil? ? property.name : "#{path}.#{property.name}"
|
87
|
+
)
|
88
|
+
end
|
89
|
+
if (additional_properties = schema.additional_properties&.resolve(@definitions))
|
90
|
+
additional_properties_schema = additional_properties.schema.resolve(@definitions)
|
91
|
+
|
92
|
+
object.public_send(additional_properties.source)&.each do |key, value|
|
93
|
+
# Don't replace the property with the same key
|
94
|
+
next if properties.key?(key = key.to_s)
|
95
|
+
|
96
|
+
# Serialize the additional property
|
97
|
+
properties[key] = serialize(
|
98
|
+
value,
|
99
|
+
additional_properties_schema,
|
100
|
+
path.nil? ? key : "#{path}.#{key}"
|
101
|
+
)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
properties
|
105
|
+
end
|
84
106
|
end
|
85
107
|
end
|
86
108
|
end
|
data/lib/jsapi/json/object.rb
CHANGED
@@ -11,16 +11,13 @@ module Jsapi
|
|
11
11
|
def initialize(attributes, schema, definitions)
|
12
12
|
# Select inherriting schema on polymorphism
|
13
13
|
if (discriminator = schema.discriminator)
|
14
|
-
schema = discriminator.resolve(
|
15
|
-
attributes[discriminator.property_name],
|
16
|
-
definitions
|
17
|
-
)
|
14
|
+
schema = discriminator.resolve(attributes[discriminator.property_name], definitions)
|
18
15
|
end
|
19
16
|
# Wrap attribute values
|
20
|
-
@raw_attributes =
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
@raw_attributes =
|
18
|
+
schema.resolve_properties(:write, definitions).transform_values do |property|
|
19
|
+
JSON.wrap(attributes[property.name], property.schema, definitions)
|
20
|
+
end
|
24
21
|
|
25
22
|
super(schema)
|
26
23
|
end
|
@@ -4,6 +4,8 @@ module Jsapi
|
|
4
4
|
module Meta
|
5
5
|
module Example
|
6
6
|
class Model < Base
|
7
|
+
include OpenAPI::Extensions
|
8
|
+
|
7
9
|
##
|
8
10
|
# :attr: description
|
9
11
|
# The optional description of the example.
|
@@ -26,10 +28,7 @@ module Jsapi
|
|
26
28
|
|
27
29
|
# Returns a hash representing the \OpenAPI example object.
|
28
30
|
def to_openapi(*)
|
29
|
-
|
30
|
-
hash[:summary] = summary if summary.present?
|
31
|
-
hash[:description] = description if description.present?
|
32
|
-
|
31
|
+
with_openapi_extensions(summary: summary, description: description).tap do |hash|
|
33
32
|
if external?
|
34
33
|
hash[:external_value] = value
|
35
34
|
else
|
@@ -5,6 +5,8 @@ module Jsapi
|
|
5
5
|
module OpenAPI
|
6
6
|
# Represents a contact object.
|
7
7
|
class Contact < Base
|
8
|
+
include Extensions
|
9
|
+
|
8
10
|
##
|
9
11
|
# :attr: email
|
10
12
|
# The email address of the contact.
|
@@ -22,11 +24,7 @@ module Jsapi
|
|
22
24
|
|
23
25
|
# Returns a hash representing the contact object.
|
24
26
|
def to_openapi(*)
|
25
|
-
|
26
|
-
name: name,
|
27
|
-
url: url,
|
28
|
-
email: email
|
29
|
-
}.compact
|
27
|
+
with_openapi_extensions(name: name, url: url, email: email)
|
30
28
|
end
|
31
29
|
end
|
32
30
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
module OpenAPI
|
6
|
+
module Extensions
|
7
|
+
# Adds an \OpenAPI extension.
|
8
|
+
#
|
9
|
+
# Raises an +ArgumentError+ if +name+ is blank.
|
10
|
+
def add_openapi_extension(name, value = nil)
|
11
|
+
raise ArgumentError, "name can't be blank" if name.blank?
|
12
|
+
|
13
|
+
openapi_extensions["x-#{name}".to_sym] = value
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns a hash containing the \OpenAPI extensions.
|
17
|
+
def openapi_extensions
|
18
|
+
@openapi_extensions ||= {}
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def with_openapi_extensions(keywords = {}) # :nodoc:
|
24
|
+
keywords.merge!(openapi_extensions)
|
25
|
+
keywords.compact!
|
26
|
+
keywords
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -5,6 +5,8 @@ module Jsapi
|
|
5
5
|
module OpenAPI
|
6
6
|
# Represents an external documentation object.
|
7
7
|
class ExternalDocumentation < Base
|
8
|
+
include Extensions
|
9
|
+
|
8
10
|
##
|
9
11
|
# :attr: description
|
10
12
|
# The optional description of the external documentation.
|
@@ -17,10 +19,7 @@ module Jsapi
|
|
17
19
|
|
18
20
|
# Returns a hash representing the external documentation object.
|
19
21
|
def to_openapi(*)
|
20
|
-
|
21
|
-
url: url,
|
22
|
-
description: description
|
23
|
-
}.compact
|
22
|
+
with_openapi_extensions(url: url, description: description)
|
24
23
|
end
|
25
24
|
end
|
26
25
|
end
|
@@ -5,6 +5,8 @@ module Jsapi
|
|
5
5
|
module OpenAPI
|
6
6
|
# Represents an info object.
|
7
7
|
class Info < Base
|
8
|
+
include Extensions
|
9
|
+
|
8
10
|
##
|
9
11
|
# :attr: contact
|
10
12
|
# The optional Contact object.
|
@@ -37,14 +39,14 @@ module Jsapi
|
|
37
39
|
|
38
40
|
# Returns a hash representing the info object.
|
39
41
|
def to_openapi(*)
|
40
|
-
|
42
|
+
with_openapi_extensions(
|
41
43
|
title: title,
|
42
44
|
version: version,
|
43
45
|
description: description,
|
44
46
|
termsOfService: terms_of_service,
|
45
47
|
contact: contact&.to_openapi,
|
46
48
|
license: license&.to_openapi
|
47
|
-
|
49
|
+
)
|
48
50
|
end
|
49
51
|
end
|
50
52
|
end
|
@@ -5,6 +5,8 @@ module Jsapi
|
|
5
5
|
module OpenAPI
|
6
6
|
# Represents a license object.
|
7
7
|
class License < Base
|
8
|
+
include Extensions
|
9
|
+
|
8
10
|
##
|
9
11
|
# :attr: name
|
10
12
|
# The name of the license.
|
@@ -17,10 +19,7 @@ module Jsapi
|
|
17
19
|
|
18
20
|
# Returns a hash representing the license object.
|
19
21
|
def to_openapi(*)
|
20
|
-
|
21
|
-
name: name,
|
22
|
-
url: url
|
23
|
-
}.compact
|
22
|
+
with_openapi_extensions(name: name, url: url)
|
24
23
|
end
|
25
24
|
end
|
26
25
|
end
|
@@ -6,6 +6,8 @@ module Jsapi
|
|
6
6
|
module Link
|
7
7
|
# Represents a link object.
|
8
8
|
class Model < Base
|
9
|
+
include Extensions
|
10
|
+
|
9
11
|
##
|
10
12
|
# :attr: description
|
11
13
|
# The optional description of the link.
|
@@ -33,13 +35,13 @@ module Jsapi
|
|
33
35
|
|
34
36
|
# Returns a hash representing the link object.
|
35
37
|
def to_openapi(*)
|
36
|
-
|
38
|
+
with_openapi_extensions(
|
37
39
|
operationId: operation_id,
|
38
40
|
parameters: parameters,
|
39
41
|
requestBody: request_body,
|
40
42
|
description: description,
|
41
43
|
server: server&.to_openapi
|
42
|
-
|
44
|
+
)
|
43
45
|
end
|
44
46
|
end
|
45
47
|
end
|
@@ -5,6 +5,8 @@ module Jsapi
|
|
5
5
|
module OpenAPI
|
6
6
|
# Represents an OAuth flow object.
|
7
7
|
class OAuthFlow < Base
|
8
|
+
include Extensions
|
9
|
+
|
8
10
|
class Scope < Base
|
9
11
|
##
|
10
12
|
# :attr: description
|
@@ -37,12 +39,12 @@ module Jsapi
|
|
37
39
|
|
38
40
|
# Returns a hash representing the OAuth flow object.
|
39
41
|
def to_openapi(version)
|
40
|
-
|
42
|
+
with_openapi_extensions(
|
41
43
|
authorizationUrl: authorization_url,
|
42
44
|
tokenUrl: token_url,
|
43
45
|
refreshUrl: (refresh_url if version.major > 2),
|
44
46
|
scopes: scopes.transform_values(&:description)
|
45
|
-
|
47
|
+
)
|
46
48
|
end
|
47
49
|
end
|
48
50
|
end
|
@@ -5,6 +5,8 @@ module Jsapi
|
|
5
5
|
module OpenAPI
|
6
6
|
# Represents an \OpenAPI object.
|
7
7
|
class Root < Base
|
8
|
+
include Extensions
|
9
|
+
|
8
10
|
##
|
9
11
|
# :attr: callbacks
|
10
12
|
# The reusable Callback objects. Applies to \OpenAPI 3.0 and higher.
|
@@ -95,38 +97,40 @@ module Jsapi
|
|
95
97
|
value.to_openapi(version)
|
96
98
|
end
|
97
99
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
callback
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
100
|
+
with_openapi_extensions(
|
101
|
+
if version.major == 2
|
102
|
+
uri = servers&.first&.then { |server| URI(server.url) }
|
103
|
+
{
|
104
|
+
swagger: '2.0',
|
105
|
+
info: info&.to_openapi,
|
106
|
+
host: host || uri&.hostname,
|
107
|
+
basePath: base_path || uri&.path,
|
108
|
+
schemes: schemes || uri&.scheme&.then { |scheme| [scheme] },
|
109
|
+
consumes: consumed_mime_types,
|
110
|
+
produces: produced_mime_types,
|
111
|
+
securityDefinitions: security_schemes,
|
112
|
+
security: security_requirements&.map(&:to_openapi),
|
113
|
+
tags: tags&.map(&:to_openapi),
|
114
|
+
externalDocs: external_docs&.to_openapi
|
115
|
+
}
|
116
|
+
else
|
117
|
+
{
|
118
|
+
openapi: version.minor.zero? ? '3.0.3' : '3.1.0',
|
119
|
+
info: info&.to_openapi,
|
120
|
+
servers: servers&.map(&:to_openapi),
|
121
|
+
components: {
|
122
|
+
callbacks: callbacks&.transform_values do |callback|
|
123
|
+
callback.to_openapi(version, definitions)
|
124
|
+
end,
|
125
|
+
links: links&.transform_values(&:to_openapi),
|
126
|
+
securitySchemes: security_schemes
|
127
|
+
}.compact.presence,
|
128
|
+
security: security_requirements&.map(&:to_openapi),
|
129
|
+
tags: tags&.map(&:to_openapi),
|
130
|
+
externalDocs: external_docs&.to_openapi
|
131
|
+
}
|
132
|
+
end
|
133
|
+
)
|
130
134
|
end
|
131
135
|
end
|
132
136
|
end
|
@@ -6,6 +6,8 @@ module Jsapi
|
|
6
6
|
module SecurityScheme
|
7
7
|
# Represents a security scheme based on an API key.
|
8
8
|
class APIKey < Base
|
9
|
+
include Extensions
|
10
|
+
|
9
11
|
##
|
10
12
|
# :attr: in
|
11
13
|
# The location of the API key. Possible values are:
|
@@ -24,12 +26,12 @@ module Jsapi
|
|
24
26
|
|
25
27
|
# Returns a hash representing the security scheme object.
|
26
28
|
def to_openapi(*)
|
27
|
-
|
29
|
+
with_openapi_extensions(
|
28
30
|
type: 'apiKey',
|
29
31
|
name: name,
|
30
32
|
in: self.in,
|
31
33
|
description: description
|
32
|
-
|
34
|
+
)
|
33
35
|
end
|
34
36
|
end
|
35
37
|
end
|
@@ -7,21 +7,26 @@ module Jsapi
|
|
7
7
|
module HTTP
|
8
8
|
# Represents a security scheme based on \HTTP basic authentication.
|
9
9
|
class Basic < Base
|
10
|
+
include Extensions
|
11
|
+
|
10
12
|
# Returns a hash representing the security scheme object.
|
11
13
|
def to_openapi(version)
|
12
14
|
version = OpenAPI::Version.from(version)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
15
|
+
|
16
|
+
with_openapi_extensions(
|
17
|
+
if version.major == 2
|
18
|
+
{
|
19
|
+
type: 'basic',
|
20
|
+
description: description
|
21
|
+
}
|
22
|
+
else
|
23
|
+
{
|
24
|
+
type: 'http',
|
25
|
+
scheme: 'basic',
|
26
|
+
description: description
|
27
|
+
}
|
28
|
+
end
|
29
|
+
)
|
25
30
|
end
|
26
31
|
end
|
27
32
|
end
|
@@ -11,6 +11,8 @@ module Jsapi
|
|
11
11
|
# Thus, a security scheme of this class is skipped when generating
|
12
12
|
# an \OpenAPI 2.0 document.
|
13
13
|
class Bearer < Base
|
14
|
+
include Extensions
|
15
|
+
|
14
16
|
##
|
15
17
|
# :attr: bearer_format
|
16
18
|
# The optional format of the bearer token.
|
@@ -22,12 +24,12 @@ module Jsapi
|
|
22
24
|
version = OpenAPI::Version.from(version)
|
23
25
|
return if version.major == 2
|
24
26
|
|
25
|
-
|
27
|
+
with_openapi_extensions(
|
26
28
|
type: 'http',
|
27
29
|
scheme: 'bearer',
|
28
30
|
bearerFormat: bearer_format,
|
29
31
|
description: description
|
30
|
-
|
32
|
+
)
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|
@@ -12,6 +12,8 @@ module Jsapi
|
|
12
12
|
# a security scheme of this class is skipped when generating an
|
13
13
|
# \OpenAPI 2.0 document.
|
14
14
|
class Other < Base
|
15
|
+
include Extensions
|
16
|
+
|
15
17
|
##
|
16
18
|
# :attr: scheme
|
17
19
|
# The mandatory \HTTP authentication scheme.
|
@@ -23,11 +25,11 @@ module Jsapi
|
|
23
25
|
version = OpenAPI::Version.from(version)
|
24
26
|
return if version.major == 2
|
25
27
|
|
26
|
-
|
28
|
+
with_openapi_extensions(
|
27
29
|
type: 'http',
|
28
30
|
scheme: scheme,
|
29
31
|
description: description
|
30
|
-
|
32
|
+
)
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|
@@ -6,6 +6,8 @@ module Jsapi
|
|
6
6
|
module SecurityScheme
|
7
7
|
# Represents a security scheme based on \OAuth2.
|
8
8
|
class OAuth2 < Base
|
9
|
+
include Extensions
|
10
|
+
|
9
11
|
##
|
10
12
|
# :attr: oauth_flows
|
11
13
|
# The hash containing the OAuth flows. Possible keys are:
|
@@ -22,10 +24,8 @@ module Jsapi
|
|
22
24
|
# Returns a hash representing the security scheme object.
|
23
25
|
def to_openapi(version)
|
24
26
|
version = Version.from(version)
|
25
|
-
|
26
|
-
|
27
|
-
description: description
|
28
|
-
}.tap do |h|
|
27
|
+
|
28
|
+
with_openapi_extensions(type: 'oauth2', description: description).tap do |h|
|
29
29
|
if oauth_flows&.any?
|
30
30
|
if version.major == 2
|
31
31
|
key, oauth_flow = oauth_flows.first
|
@@ -37,7 +37,7 @@ module Jsapi
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
40
|
-
end
|
40
|
+
end
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -9,6 +9,8 @@ module Jsapi
|
|
9
9
|
# OpenID Connect was introduced with \OpenAPI 3.0. Thus, a security scheme of
|
10
10
|
# this class is skipped when generating an \OpenAPI 2.0 document.
|
11
11
|
class OpenIDConnect < Base
|
12
|
+
include Extensions
|
13
|
+
|
12
14
|
##
|
13
15
|
# :attr: open_id_connect_url
|
14
16
|
attribute :open_id_connect_url, String
|
@@ -19,11 +21,11 @@ module Jsapi
|
|
19
21
|
version = Version.from(version)
|
20
22
|
return if version.major == 2
|
21
23
|
|
22
|
-
|
24
|
+
with_openapi_extensions(
|
23
25
|
type: 'openIdConnect',
|
24
26
|
openIdConnectUrl: open_id_connect_url,
|
25
27
|
description: description
|
26
|
-
|
28
|
+
)
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
@@ -5,6 +5,8 @@ module Jsapi
|
|
5
5
|
module OpenAPI
|
6
6
|
# Represents a server object.
|
7
7
|
class Server < Base
|
8
|
+
include Extensions
|
9
|
+
|
8
10
|
##
|
9
11
|
# :attr: description
|
10
12
|
# The optional description of the server.
|
@@ -22,11 +24,11 @@ module Jsapi
|
|
22
24
|
|
23
25
|
# Returns a hash representing the server object.
|
24
26
|
def to_openapi(*)
|
25
|
-
|
27
|
+
with_openapi_extensions(
|
26
28
|
url: url,
|
27
29
|
description: description,
|
28
30
|
variables: variables&.transform_values(&:to_openapi)
|
29
|
-
|
31
|
+
)
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
@@ -5,6 +5,8 @@ module Jsapi
|
|
5
5
|
module OpenAPI
|
6
6
|
# Represents a server variable object.
|
7
7
|
class ServerVariable < Base
|
8
|
+
include Extensions
|
9
|
+
|
8
10
|
##
|
9
11
|
# :attr: default
|
10
12
|
# The default value of the server variable.
|
@@ -22,11 +24,11 @@ module Jsapi
|
|
22
24
|
|
23
25
|
# Returns a hash representing the server variable object.
|
24
26
|
def to_openapi(*)
|
25
|
-
|
27
|
+
with_openapi_extensions(
|
26
28
|
default: default,
|
27
29
|
enum: enum.presence, # must not be empty
|
28
30
|
description: description
|
29
|
-
|
31
|
+
)
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
@@ -5,6 +5,8 @@ module Jsapi
|
|
5
5
|
module OpenAPI
|
6
6
|
# Represents a tag object.
|
7
7
|
class Tag < Base
|
8
|
+
include Extensions
|
9
|
+
|
8
10
|
##
|
9
11
|
# :attr: description
|
10
12
|
# The description of the tag.
|
@@ -22,11 +24,11 @@ module Jsapi
|
|
22
24
|
|
23
25
|
# Returns a hash representing the tag object.
|
24
26
|
def to_openapi(*)
|
25
|
-
|
27
|
+
with_openapi_extensions(
|
26
28
|
name: name,
|
27
29
|
description: description,
|
28
30
|
externalDocs: external_docs&.to_openapi
|
29
|
-
|
31
|
+
)
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
data/lib/jsapi/meta/openapi.rb
CHANGED
data/lib/jsapi/meta/operation.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
module Jsapi
|
4
4
|
module Meta
|
5
5
|
class Operation < Base
|
6
|
+
include OpenAPI::Extensions
|
7
|
+
|
6
8
|
##
|
7
9
|
# :attr: callbacks
|
8
10
|
# The optional callbacks. Applies to \OpenAPI 3.0 and higher.
|
@@ -133,7 +135,8 @@ module Jsapi
|
|
133
135
|
# Returns a hash representing the \OpenAPI operation object.
|
134
136
|
def to_openapi(version, definitions)
|
135
137
|
version = OpenAPI::Version.from(version)
|
136
|
-
|
138
|
+
|
139
|
+
with_openapi_extensions(
|
137
140
|
operationId: name,
|
138
141
|
tags: tags,
|
139
142
|
summary: summary,
|
@@ -141,7 +144,7 @@ module Jsapi
|
|
141
144
|
externalDocs: external_docs&.to_openapi,
|
142
145
|
deprecated: deprecated?.presence,
|
143
146
|
security: security_requirements&.map(&:to_openapi)
|
144
|
-
|
147
|
+
).tap do |hash|
|
145
148
|
if version.major == 2
|
146
149
|
hash[:consumes] = consumed_mime_types if consumed_mime_types
|
147
150
|
hash[:produces] = produced_mime_types if produced_mime_types
|
@@ -170,7 +173,7 @@ module Jsapi
|
|
170
173
|
callback.to_openapi(version, definitions)
|
171
174
|
end
|
172
175
|
end
|
173
|
-
end
|
176
|
+
end
|
174
177
|
end
|
175
178
|
end
|
176
179
|
end
|
@@ -4,6 +4,8 @@ module Jsapi
|
|
4
4
|
module Meta
|
5
5
|
module Parameter
|
6
6
|
class Model < Base
|
7
|
+
include OpenAPI::Extensions
|
8
|
+
|
7
9
|
##
|
8
10
|
# :attr: deprecated
|
9
11
|
# Specifies whether or not the parameter is deprecated.
|
@@ -87,32 +89,34 @@ module Jsapi
|
|
87
89
|
else
|
88
90
|
parameter_name = schema.array? ? "#{name}[]" : name
|
89
91
|
[
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
92
|
+
with_openapi_extensions(
|
93
|
+
if version.major == 2
|
94
|
+
{
|
95
|
+
name: parameter_name,
|
96
|
+
in: self.in,
|
97
|
+
description: description,
|
98
|
+
required: required?.presence,
|
99
|
+
allowEmptyValue: allow_empty_value?.presence,
|
100
|
+
collectionFormat: ('multi' if schema.array?)
|
101
|
+
}.merge(schema.to_openapi(version))
|
102
|
+
else
|
103
|
+
{
|
104
|
+
name: parameter_name,
|
105
|
+
in: self.in,
|
106
|
+
description: description,
|
107
|
+
required: required?.presence,
|
108
|
+
allowEmptyValue: allow_empty_value?.presence,
|
109
|
+
deprecated: deprecated?.presence,
|
110
|
+
schema: schema.to_openapi(version),
|
111
|
+
examples: examples&.transform_values(&:to_openapi)
|
112
|
+
|
113
|
+
# NOTE: collectionFormat is replaced by style and explode.
|
114
|
+
# The default values for query parameters are:
|
115
|
+
# - style: 'form'
|
116
|
+
# - explode: true
|
117
|
+
}
|
118
|
+
end
|
119
|
+
)
|
116
120
|
]
|
117
121
|
end
|
118
122
|
end
|
@@ -141,27 +145,29 @@ module Jsapi
|
|
141
145
|
description = property_schema.description
|
142
146
|
allow_empty_value = property.schema.existence <= Existence::ALLOW_EMPTY
|
143
147
|
[
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
148
|
+
with_openapi_extensions(
|
149
|
+
if version.major == 2
|
150
|
+
{
|
151
|
+
name: parameter_name,
|
152
|
+
in: self.in,
|
153
|
+
description: description,
|
154
|
+
required: required,
|
155
|
+
allowEmptyValue: allow_empty_value.presence,
|
156
|
+
collectionFormat: ('multi' if property_schema.array?)
|
157
|
+
}.merge(property_schema.to_openapi(version))
|
158
|
+
else
|
159
|
+
{
|
160
|
+
name: parameter_name,
|
161
|
+
in: self.in,
|
162
|
+
description: description,
|
163
|
+
required: required,
|
164
|
+
allowEmptyValue: allow_empty_value.presence,
|
165
|
+
deprecated: deprecated,
|
166
|
+
schema: property_schema.to_openapi(version).except(:deprecated),
|
167
|
+
examples: examples&.transform_values(&:to_openapi)
|
168
|
+
}
|
169
|
+
end
|
170
|
+
)
|
165
171
|
]
|
166
172
|
end
|
167
173
|
end
|
@@ -4,6 +4,8 @@ module Jsapi
|
|
4
4
|
module Meta
|
5
5
|
module RequestBody
|
6
6
|
class Model < Base
|
7
|
+
include OpenAPI::Extensions
|
8
|
+
|
7
9
|
##
|
8
10
|
# :attr: description
|
9
11
|
# The optional description of the request body.
|
@@ -44,12 +46,12 @@ module Jsapi
|
|
44
46
|
in: 'body',
|
45
47
|
description: description,
|
46
48
|
required: required?
|
47
|
-
}.merge(schema.to_openapi('2.0')).compact
|
49
|
+
}.merge(schema.to_openapi('2.0')).merge(openapi_extensions).compact
|
48
50
|
end
|
49
51
|
|
50
52
|
# Returns a hash representing the \OpenAPI 3.x request body object.
|
51
53
|
def to_openapi(version)
|
52
|
-
|
54
|
+
with_openapi_extensions(
|
53
55
|
description: description,
|
54
56
|
content: {
|
55
57
|
'application/json' => {
|
@@ -58,7 +60,7 @@ module Jsapi
|
|
58
60
|
}.compact
|
59
61
|
},
|
60
62
|
required: required?
|
61
|
-
|
63
|
+
)
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
@@ -4,6 +4,8 @@ module Jsapi
|
|
4
4
|
module Meta
|
5
5
|
module Response
|
6
6
|
class Model < Base
|
7
|
+
include OpenAPI::Extensions
|
8
|
+
|
7
9
|
##
|
8
10
|
# :attr: description
|
9
11
|
# The optional description of the response.
|
@@ -44,28 +46,31 @@ module Jsapi
|
|
44
46
|
# Returns a hash representing the \OpenAPI response object.
|
45
47
|
def to_openapi(version, definitions)
|
46
48
|
version = OpenAPI::Version.from(version)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
49
|
+
|
50
|
+
with_openapi_extensions(
|
51
|
+
if version.major == 2
|
52
|
+
{
|
53
|
+
description: description,
|
54
|
+
schema: schema.to_openapi(version),
|
55
|
+
examples: (
|
56
|
+
if (example = examples&.values&.first).present?
|
57
|
+
{ 'application/json' => example.resolve(definitions).value }
|
58
|
+
end
|
59
|
+
)
|
60
|
+
}
|
61
|
+
else
|
62
|
+
{
|
63
|
+
description: description,
|
64
|
+
content: {
|
65
|
+
'application/json' => {
|
66
|
+
schema: schema.to_openapi(version),
|
67
|
+
examples: examples&.transform_values(&:to_openapi)
|
68
|
+
}.compact
|
69
|
+
},
|
70
|
+
links: links&.transform_values(&:to_openapi)
|
71
|
+
}
|
72
|
+
end
|
73
|
+
)
|
69
74
|
end
|
70
75
|
end
|
71
76
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
module Schema
|
6
|
+
class AdditionalProperties < Meta::Base
|
7
|
+
#
|
8
|
+
# :attr: schema
|
9
|
+
# The Schema of additional properties.
|
10
|
+
attribute :schema, Schema, writer: false
|
11
|
+
|
12
|
+
##
|
13
|
+
# :attr: source
|
14
|
+
# The method to read additional properties when serializing an object.
|
15
|
+
# The default method is +additional_properties+.
|
16
|
+
attribute :source, Symbol, default: :additional_properties
|
17
|
+
|
18
|
+
delegate_missing_to :schema
|
19
|
+
|
20
|
+
def initialize(keywords = {})
|
21
|
+
keywords = keywords.dup
|
22
|
+
super(keywords.extract!(:source))
|
23
|
+
|
24
|
+
@schema = Schema.new(keywords)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -4,6 +4,8 @@ module Jsapi
|
|
4
4
|
module Meta
|
5
5
|
module Schema
|
6
6
|
class Base < Meta::Base
|
7
|
+
include OpenAPI::Extensions
|
8
|
+
|
7
9
|
TYPES = %w[array boolean integer number object string].freeze # :nodoc:
|
8
10
|
|
9
11
|
TYPES.each do |type|
|
@@ -96,37 +98,40 @@ module Jsapi
|
|
96
98
|
# Returns a hash representing the \OpenAPI schema object.
|
97
99
|
def to_openapi(version)
|
98
100
|
version = OpenAPI::Version.from(version)
|
99
|
-
if version.major == 2
|
100
|
-
# OpenAPI 2.0
|
101
|
-
{
|
102
|
-
type: type,
|
103
|
-
example: examples&.first
|
104
|
-
}
|
105
|
-
elsif version.minor.zero?
|
106
|
-
# OpenAPI 3.0
|
107
|
-
{
|
108
|
-
type: type,
|
109
|
-
nullable: nullable?.presence,
|
110
|
-
examples: examples,
|
111
|
-
deprecated: deprecated?.presence
|
112
|
-
}
|
113
|
-
else
|
114
|
-
# OpenAPI 3.1
|
115
|
-
{
|
116
|
-
type: nullable? ? [type, 'null'] : type,
|
117
|
-
examples: examples,
|
118
|
-
deprecated: deprecated?.presence
|
119
|
-
}
|
120
|
-
end.tap do |hash|
|
121
|
-
hash[:title] = title
|
122
|
-
hash[:description] = description
|
123
|
-
hash[:default] = default
|
124
|
-
hash[:externalDocs] = external_docs&.to_openapi
|
125
101
|
|
126
|
-
|
127
|
-
|
102
|
+
with_openapi_extensions(
|
103
|
+
if version.major == 2
|
104
|
+
# OpenAPI 2.0
|
105
|
+
{
|
106
|
+
type: type,
|
107
|
+
example: examples&.first
|
108
|
+
}
|
109
|
+
elsif version.minor.zero?
|
110
|
+
# OpenAPI 3.0
|
111
|
+
{
|
112
|
+
type: type,
|
113
|
+
nullable: nullable?.presence,
|
114
|
+
examples: examples,
|
115
|
+
deprecated: deprecated?.presence
|
116
|
+
}
|
117
|
+
else
|
118
|
+
# OpenAPI 3.1
|
119
|
+
{
|
120
|
+
type: nullable? ? [type, 'null'] : type,
|
121
|
+
examples: examples,
|
122
|
+
deprecated: deprecated?.presence
|
123
|
+
}
|
124
|
+
end.tap do |hash|
|
125
|
+
hash[:title] = title
|
126
|
+
hash[:description] = description
|
127
|
+
hash[:default] = default
|
128
|
+
hash[:externalDocs] = external_docs&.to_openapi
|
129
|
+
|
130
|
+
validations.each_value do |validation|
|
131
|
+
hash.merge!(validation.to_openapi_validation(version))
|
132
|
+
end
|
128
133
|
end
|
129
|
-
|
134
|
+
)
|
130
135
|
end
|
131
136
|
|
132
137
|
def type # :nodoc:
|
@@ -4,15 +4,21 @@ module Jsapi
|
|
4
4
|
module Meta
|
5
5
|
module Schema
|
6
6
|
class Object < Base
|
7
|
+
##
|
8
|
+
# :attr: additional_properties
|
9
|
+
# The AdditionalProperties.
|
10
|
+
attribute :additional_properties, AdditionalProperties
|
11
|
+
|
7
12
|
##
|
8
13
|
# :attr: all_of_references
|
9
14
|
attribute :all_of_references, [Reference], default: []
|
10
15
|
|
11
|
-
alias :all_of= :all_of_references=
|
16
|
+
alias :all_of= :all_of_references= # :nodoc:
|
12
17
|
alias :add_all_of :add_all_of_reference
|
13
18
|
|
14
19
|
##
|
15
20
|
# :attr: discriminator
|
21
|
+
# The Discriminator.
|
16
22
|
attribute :discriminator, Discriminator
|
17
23
|
|
18
24
|
##
|
@@ -47,6 +53,7 @@ module Jsapi
|
|
47
53
|
super.merge(
|
48
54
|
allOf: all_of_references.map(&:to_json_schema).presence,
|
49
55
|
properties: properties.transform_values(&:to_json_schema),
|
56
|
+
additionalProperties: additional_properties&.to_json_schema,
|
50
57
|
required: properties.values.select(&:required?).map(&:name)
|
51
58
|
).compact
|
52
59
|
end
|
@@ -60,6 +67,7 @@ module Jsapi
|
|
60
67
|
properties: properties.transform_values do |property|
|
61
68
|
property.to_openapi(version)
|
62
69
|
end,
|
70
|
+
additionalProperties: additional_properties&.to_openapi(version),
|
63
71
|
required: properties.values.select(&:required?).map(&:name)
|
64
72
|
).compact
|
65
73
|
end
|
data/lib/jsapi/meta/schema.rb
CHANGED
@@ -4,13 +4,14 @@ require_relative 'schema/conversion'
|
|
4
4
|
require_relative 'schema/boundary'
|
5
5
|
require_relative 'schema/delegator'
|
6
6
|
require_relative 'schema/reference'
|
7
|
-
require_relative 'schema/discriminator'
|
8
7
|
require_relative 'schema/base'
|
9
8
|
require_relative 'schema/boolean'
|
10
9
|
require_relative 'schema/array'
|
11
10
|
require_relative 'schema/numeric'
|
12
11
|
require_relative 'schema/integer'
|
13
12
|
require_relative 'schema/number'
|
13
|
+
require_relative 'schema/additional_properties'
|
14
|
+
require_relative 'schema/discriminator'
|
14
15
|
require_relative 'schema/object'
|
15
16
|
require_relative 'schema/string'
|
16
17
|
require_relative 'schema/validation'
|
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: 0.
|
4
|
+
version: 0.3.0
|
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: 2024-07-
|
11
|
+
date: 2024-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Jsapi can be used to read requests, produce responses and create OpenAPI
|
14
14
|
documents
|
@@ -66,6 +66,7 @@ files:
|
|
66
66
|
- lib/jsapi/meta/openapi/callback/model.rb
|
67
67
|
- lib/jsapi/meta/openapi/callback/reference.rb
|
68
68
|
- lib/jsapi/meta/openapi/contact.rb
|
69
|
+
- lib/jsapi/meta/openapi/extensions.rb
|
69
70
|
- lib/jsapi/meta/openapi/external_documentation.rb
|
70
71
|
- lib/jsapi/meta/openapi/info.rb
|
71
72
|
- lib/jsapi/meta/openapi/license.rb
|
@@ -102,6 +103,7 @@ files:
|
|
102
103
|
- lib/jsapi/meta/response/model.rb
|
103
104
|
- lib/jsapi/meta/response/reference.rb
|
104
105
|
- lib/jsapi/meta/schema.rb
|
106
|
+
- lib/jsapi/meta/schema/additional_properties.rb
|
105
107
|
- lib/jsapi/meta/schema/array.rb
|
106
108
|
- lib/jsapi/meta/schema/base.rb
|
107
109
|
- lib/jsapi/meta/schema/boolean.rb
|