jsapi 0.1.2 → 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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jsapi/controller/methods.rb +4 -3
  3. data/lib/jsapi/controller/parameters.rb +2 -5
  4. data/lib/jsapi/controller/response.rb +48 -24
  5. data/lib/jsapi/dsl/parameter.rb +0 -10
  6. data/lib/jsapi/dsl/request_body.rb +0 -10
  7. data/lib/jsapi/dsl/response.rb +0 -10
  8. data/lib/jsapi/dsl/schema.rb +1 -1
  9. data/lib/jsapi/json/array.rb +2 -3
  10. data/lib/jsapi/json/null.rb +2 -2
  11. data/lib/jsapi/json/object.rb +6 -9
  12. data/lib/jsapi/json/string.rb +25 -11
  13. data/lib/jsapi/json/value.rb +4 -4
  14. data/lib/jsapi/meta/example/model.rb +3 -4
  15. data/lib/jsapi/meta/openapi/contact.rb +3 -5
  16. data/lib/jsapi/meta/openapi/extensions.rb +31 -0
  17. data/lib/jsapi/meta/openapi/external_documentation.rb +3 -4
  18. data/lib/jsapi/meta/openapi/info.rb +4 -2
  19. data/lib/jsapi/meta/openapi/license.rb +3 -4
  20. data/lib/jsapi/meta/openapi/link/model.rb +4 -2
  21. data/lib/jsapi/meta/openapi/oauth_flow.rb +4 -2
  22. data/lib/jsapi/meta/openapi/root.rb +36 -31
  23. data/lib/jsapi/meta/openapi/security_scheme/api_key.rb +4 -2
  24. data/lib/jsapi/meta/openapi/security_scheme/http/basic.rb +17 -12
  25. data/lib/jsapi/meta/openapi/security_scheme/http/bearer.rb +4 -2
  26. data/lib/jsapi/meta/openapi/security_scheme/http/other.rb +4 -2
  27. data/lib/jsapi/meta/openapi/security_scheme/oauth2.rb +5 -5
  28. data/lib/jsapi/meta/openapi/security_scheme/open_id_connect.rb +4 -2
  29. data/lib/jsapi/meta/openapi/server.rb +4 -2
  30. data/lib/jsapi/meta/openapi/server_variable.rb +4 -2
  31. data/lib/jsapi/meta/openapi/tag.rb +4 -2
  32. data/lib/jsapi/meta/openapi.rb +1 -0
  33. data/lib/jsapi/meta/operation.rb +6 -3
  34. data/lib/jsapi/meta/parameter/model.rb +56 -48
  35. data/lib/jsapi/meta/property.rb +3 -1
  36. data/lib/jsapi/meta/request_body/model.rb +6 -3
  37. data/lib/jsapi/meta/response/model.rb +28 -22
  38. data/lib/jsapi/meta/schema/additional_properties.rb +29 -0
  39. data/lib/jsapi/meta/schema/array.rb +9 -1
  40. data/lib/jsapi/meta/schema/base.rb +34 -29
  41. data/lib/jsapi/meta/schema/object.rb +10 -2
  42. data/lib/jsapi/meta/schema/reference.rb +0 -3
  43. data/lib/jsapi/meta/schema/string.rb +2 -6
  44. data/lib/jsapi/meta/schema.rb +3 -4
  45. data/lib/jsapi/version.rb +3 -3
  46. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fbf64d8068afe39168667e9f907654d308ab933d7688c1a10a7c6341f66a13d5
4
- data.tar.gz: 006af1f3b5fec80a643c7dab1bdc82917428c355930c434302df465177235359
3
+ metadata.gz: 78a92c9f73f4a39ede65ad5b0b5646db67dc8b9e2b3ca444b6de32fdb75e349a
4
+ data.tar.gz: e235535541854c172f578cce7cf112ceebe880971643cb33125a76cc61bbd88a
5
5
  SHA512:
6
- metadata.gz: 04a02c4e688e8c02cf7cbb4ee66356bdcb570fa9ff89a8ba3303d52f4713d7bc5c8bbbddafd22b3871d3de960e7606f25dd9496d39731f0fa0e095ffa53688a0
7
- data.tar.gz: 5099312a76a600aed362733b23bf4e358ba18b3f5a9f060258cb5aabed3caecab8d28afd9034844ce8619adf5a811f418c7fc19b28f67738392d0ec8becc659e
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. The object
17
- # returned by the block is implicitly rendered according to the appropriate
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 are
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
- item_schema = schema.items.resolve(@definitions)
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
- return if object.blank? # {}
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
@@ -71,6 +51,8 @@ module Jsapi
71
51
  object.to_date
72
52
  when 'date-time'
73
53
  object.to_datetime
54
+ when 'duration'
55
+ object.iso8601
74
56
  else
75
57
  object.to_s
76
58
  end
@@ -79,6 +61,48 @@ module Jsapi
79
61
  object
80
62
  end
81
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
82
106
  end
83
107
  end
84
108
  end
@@ -24,16 +24,6 @@ module Jsapi
24
24
  # Specifies the location of the parameter.
25
25
  #
26
26
  # See Meta::Parameter::Model#in for further information.
27
-
28
- ##
29
- # :method: ref
30
- # :args: name
31
- # Specifies the name of the reusable parameter to be referred.
32
-
33
- ##
34
- # :method: schema
35
- # :args: name
36
- # Specifies the name of the reusable schema to be referred.
37
27
  end
38
28
  end
39
29
  end
@@ -17,16 +17,6 @@ module Jsapi
17
17
  # :method: description
18
18
  # :args: arg
19
19
  # Specifies the description of the request body.
20
-
21
- ##
22
- # :method: ref
23
- # :args: name
24
- # Specifies the name of the reusable request body to be referred.
25
-
26
- ##
27
- # :method: schema
28
- # :args: name
29
- # Specifies the name of the reusable schema to be referred.
30
20
  end
31
21
  end
32
22
  end
@@ -47,16 +47,6 @@ module Jsapi
47
47
  # Specifies the locale to be used when rendering a response.
48
48
  #
49
49
  # locale :en
50
-
51
- ##
52
- # :method: ref
53
- # :args: name
54
- # Specifies the name of the reusable response to be referred.
55
-
56
- ##
57
- # :method: schema
58
- # :args: name
59
- # Specifies the name of the reusable schema to be referred.
60
50
  end
61
51
  end
62
52
  end
@@ -8,7 +8,7 @@ module Jsapi
8
8
  # Includes all of the properties from +schemas+. Each argument must be the name of
9
9
  # a schema defined by ClassMethods#api_schema or Definitions#schema.
10
10
  def all_of(*schemas)
11
- schemas.each { |schema| _meta_model.add_all_of({ schema: schema }) }
11
+ schemas.each { |schema| _meta_model.add_all_of({ ref: schema }) }
12
12
  end
13
13
 
14
14
  ##
@@ -11,7 +11,7 @@ module Jsapi
11
11
  end
12
12
  end
13
13
 
14
- # Returns +true+ if it contains no elements, +false+ otherwise.
14
+ # Returns true if it contains no elements, false otherwise.
15
15
  def empty?
16
16
  @elements.empty?
17
17
  end
@@ -20,8 +20,7 @@ module Jsapi
20
20
  "#<#{self.class.name} [#{@elements.map(&:inspect).join(', ')}]>"
21
21
  end
22
22
 
23
- # See Value#validate.
24
- def validate(errors)
23
+ def validate(errors) # :nodoc:
25
24
  return false unless super
26
25
 
27
26
  @elements.map { |element| element.validate(errors) }.all?
@@ -5,7 +5,7 @@ module Jsapi
5
5
  # Represents +null+.
6
6
  class Null < Value
7
7
 
8
- # Returns allways +true+.
8
+ # Returns true.
9
9
  def empty?
10
10
  true
11
11
  end
@@ -14,7 +14,7 @@ module Jsapi
14
14
  "#<#{self.class}>"
15
15
  end
16
16
 
17
- # Returns allways +true+.
17
+ # Returns true.
18
18
  def null?
19
19
  true
20
20
  end
@@ -11,21 +11,18 @@ 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 = schema.resolve_properties(:write, definitions)
21
- .transform_values do |property|
22
- JSON.wrap(attributes[property.name], property.schema, definitions)
23
- end
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
27
24
 
28
- # Returns +true+ if all attributes are empty, +false+ otherwise.
25
+ # Returns true if all attributes are empty, false otherwise.
29
26
  def empty?
30
27
  @raw_attributes.values.all?(&:empty?)
31
28
  end
@@ -8,22 +8,36 @@ module Jsapi
8
8
 
9
9
  def initialize(value, schema)
10
10
  super(schema)
11
- @value = schema.convert(
12
- case schema.format
13
- when 'date'
14
- value.to_date
15
- when 'date-time'
16
- value.to_datetime
17
- else
18
- value.to_s
11
+
12
+ @value =
13
+ begin
14
+ case schema.format
15
+ when 'date'
16
+ value.to_date
17
+ when 'date-time'
18
+ value.to_datetime
19
+ when 'duration'
20
+ ActiveSupport::Duration.parse(value)
21
+ else
22
+ value.to_s
23
+ end
24
+ rescue StandardError => e
25
+ @error = e
26
+ value
19
27
  end
20
- )
28
+ @value = schema.convert(@value) unless defined? @error
21
29
  end
22
30
 
23
- # See Value#empty?.
24
- def empty?
31
+ def empty? # :nodoc:
25
32
  value.blank?
26
33
  end
34
+
35
+ def validate(errors) # :nodoc:
36
+ return super unless defined? @error
37
+
38
+ errors.add(:base, :invalid)
39
+ false
40
+ end
27
41
  end
28
42
  end
29
43
  end
@@ -14,7 +14,7 @@ module Jsapi
14
14
  end
15
15
 
16
16
  # Used by #validate to test whether or not it is empty.
17
- # Returns +false+ by default.
17
+ # Returns false by default.
18
18
  def empty?
19
19
  false
20
20
  end
@@ -23,13 +23,13 @@ module Jsapi
23
23
  "#<#{self.class} #{value.inspect}>"
24
24
  end
25
25
 
26
- # Used by #validate to test whether or not it is +null+.
27
- # Returns +false+ by default.
26
+ # Used by #validate to test whether or not it is null.
27
+ # Returns false by default.
28
28
  def null?
29
29
  false
30
30
  end
31
31
 
32
- # Validates it against #schema. Returns +true+ if it is valid, +false+ otherwise.
32
+ # Validates it against #schema. Returns true if it is valid, false otherwise.
33
33
  # Detected errors are added to +errors+.
34
34
  def validate(errors)
35
35
  unless schema.existence.reach?(self)
@@ -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
- {}.tap do |hash|
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
- }.compact
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
- }.compact
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
- }.compact
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,37 +97,40 @@ module Jsapi
95
97
  value.to_openapi(version)
96
98
  end
97
99
 
98
- if version.major == 2
99
- {
100
- swagger: '2.0',
101
- info: info&.to_openapi,
102
- host: host,
103
- basePath: base_path,
104
- schemes: schemes,
105
- consumes: consumed_mime_types,
106
- produces: produced_mime_types,
107
- securityDefinitions: security_schemes,
108
- security: security_requirements&.map(&:to_openapi),
109
- tags: tags&.map(&:to_openapi),
110
- externalDocs: external_docs&.to_openapi
111
- }
112
- else
113
- {
114
- openapi: version.minor.zero? ? '3.0.3' : '3.1.0',
115
- info: info&.to_openapi,
116
- servers: servers&.map(&:to_openapi),
117
- components: {
118
- callbacks: callbacks&.transform_values do |callback|
119
- callback.to_openapi(version, definitions)
120
- end,
121
- links: links&.transform_values(&:to_openapi),
122
- securitySchemes: security_schemes
123
- }.compact.presence,
124
- security: security_requirements&.map(&:to_openapi),
125
- tags: tags&.map(&:to_openapi),
126
- externalDocs: external_docs&.to_openapi
127
- }
128
- end.compact
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
+ )
129
134
  end
130
135
  end
131
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
- }.compact
34
+ )
33
35
  end
34
36
  end
35
37
  end