jsapi 1.4 → 2.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jsapi/controller/actions/class_methods.rb +61 -0
  3. data/lib/jsapi/controller/actions.rb +13 -0
  4. data/lib/jsapi/controller/authentication/class_methods.rb +65 -0
  5. data/lib/jsapi/controller/authentication/credentials/api_key.rb +24 -0
  6. data/lib/jsapi/controller/authentication/credentials/http/base.rb +25 -0
  7. data/lib/jsapi/controller/authentication/credentials/http/basic.rb +34 -0
  8. data/lib/jsapi/controller/authentication/credentials/http/bearer.rb +30 -0
  9. data/lib/jsapi/controller/authentication/credentials/http.rb +5 -0
  10. data/lib/jsapi/controller/authentication/credentials.rb +38 -0
  11. data/lib/jsapi/controller/authentication.rb +70 -0
  12. data/lib/jsapi/controller/base.rb +5 -4
  13. data/lib/jsapi/controller/methods/callbacks/callback.rb +80 -0
  14. data/lib/jsapi/controller/methods/callbacks/class_methods.rb +62 -0
  15. data/lib/jsapi/controller/methods/callbacks.rb +54 -0
  16. data/lib/jsapi/controller/methods.rb +209 -116
  17. data/lib/jsapi/controller/parameters.rb +24 -20
  18. data/lib/jsapi/controller/response.rb +71 -39
  19. data/lib/jsapi/controller.rb +2 -1
  20. data/lib/jsapi/dsl/base.rb +38 -5
  21. data/lib/jsapi/dsl/class_methods.rb +2 -2
  22. data/lib/jsapi/dsl/definitions.rb +41 -27
  23. data/lib/jsapi/dsl/operation.rb +10 -109
  24. data/lib/jsapi/dsl/parameter.rb +1 -1
  25. data/lib/jsapi/dsl/path.rb +41 -18
  26. data/lib/jsapi/dsl/request_body.rb +1 -1
  27. data/lib/jsapi/dsl/response.rb +9 -6
  28. data/lib/jsapi/dsl/schema.rb +11 -5
  29. data/lib/jsapi/dsl/shared_operation_methods.rb +140 -0
  30. data/lib/jsapi/dsl.rb +1 -2
  31. data/lib/jsapi/json/array.rb +2 -2
  32. data/lib/jsapi/json/object.rb +6 -6
  33. data/lib/jsapi/json.rb +4 -6
  34. data/lib/jsapi/media/range.rb +102 -0
  35. data/lib/jsapi/media/type.rb +70 -0
  36. data/lib/jsapi/media/type_and_subtype.rb +38 -0
  37. data/lib/jsapi/media.rb +9 -0
  38. data/lib/jsapi/messages.rb +19 -0
  39. data/lib/jsapi/meta/callback/base.rb +63 -8
  40. data/lib/jsapi/meta/content.rb +59 -0
  41. data/lib/jsapi/meta/definitions.rb +299 -153
  42. data/lib/jsapi/meta/example/base.rb +41 -8
  43. data/lib/jsapi/meta/existence.rb +4 -2
  44. data/lib/jsapi/meta/header/base.rb +4 -2
  45. data/lib/jsapi/meta/info.rb +3 -1
  46. data/lib/jsapi/meta/license.rb +11 -5
  47. data/lib/jsapi/meta/model/attributes/class_methods.rb +150 -0
  48. data/lib/jsapi/meta/model/attributes/frozen_error.rb +16 -0
  49. data/lib/jsapi/meta/model/attributes/type_caster.rb +56 -0
  50. data/lib/jsapi/meta/model/attributes.rb +24 -118
  51. data/lib/jsapi/meta/model/base.rb +2 -5
  52. data/lib/jsapi/meta/model/reference.rb +46 -10
  53. data/lib/jsapi/meta/model/wrappable.rb +23 -0
  54. data/lib/jsapi/meta/model/wrapper.rb +26 -0
  55. data/lib/jsapi/meta/model.rb +2 -1
  56. data/lib/jsapi/meta/oauth_flow.rb +1 -1
  57. data/lib/jsapi/meta/openapi/extensions.rb +5 -6
  58. data/lib/jsapi/meta/openapi/version.rb +16 -4
  59. data/lib/jsapi/meta/operation.rb +177 -71
  60. data/lib/jsapi/meta/parameter/base.rb +10 -6
  61. data/lib/jsapi/meta/parameter/wrapper.rb +13 -0
  62. data/lib/jsapi/meta/parameter.rb +3 -0
  63. data/lib/jsapi/meta/path.rb +59 -13
  64. data/lib/jsapi/meta/pathname.rb +6 -3
  65. data/lib/jsapi/meta/property.rb +10 -0
  66. data/lib/jsapi/meta/request_body/base.rb +69 -32
  67. data/lib/jsapi/meta/request_body/wrapper.rb +13 -0
  68. data/lib/jsapi/meta/request_body.rb +3 -0
  69. data/lib/jsapi/meta/rescue_handler.rb +18 -17
  70. data/lib/jsapi/meta/response/base.rb +82 -58
  71. data/lib/jsapi/meta/response/reference.rb +11 -1
  72. data/lib/jsapi/meta/response/wrapper.rb +26 -0
  73. data/lib/jsapi/meta/response.rb +3 -0
  74. data/lib/jsapi/meta/schema/additional_properties.rb +8 -0
  75. data/lib/jsapi/meta/schema/array.rb +20 -8
  76. data/lib/jsapi/meta/schema/base.rb +10 -9
  77. data/lib/jsapi/meta/schema/boundary.rb +1 -0
  78. data/lib/jsapi/meta/schema/numeric.rb +26 -20
  79. data/lib/jsapi/meta/schema/object.rb +60 -44
  80. data/lib/jsapi/meta/schema/reference.rb +1 -8
  81. data/lib/jsapi/meta/schema/string.rb +12 -6
  82. data/lib/jsapi/meta/schema/wrapper.rb +31 -0
  83. data/lib/jsapi/meta/schema.rb +22 -9
  84. data/lib/jsapi/meta/security_requirement.rb +2 -2
  85. data/lib/jsapi/meta/security_scheme/api_key.rb +5 -2
  86. data/lib/jsapi/meta/security_scheme/base.rb +7 -5
  87. data/lib/jsapi/meta/security_scheme/http/basic.rb +5 -7
  88. data/lib/jsapi/meta/security_scheme/http/bearer.rb +5 -5
  89. data/lib/jsapi/meta/security_scheme/http/other.rb +1 -3
  90. data/lib/jsapi/meta/security_scheme/mutual_tls.rb +1 -3
  91. data/lib/jsapi/meta/security_scheme/oauth2.rb +18 -13
  92. data/lib/jsapi/meta/security_scheme/open_id_connect.rb +4 -4
  93. data/lib/jsapi/meta/security_scheme.rb +4 -4
  94. data/lib/jsapi/meta/server.rb +4 -2
  95. data/lib/jsapi/meta/tag.rb +9 -3
  96. data/lib/jsapi/meta.rb +2 -1
  97. data/lib/jsapi/model/base.rb +1 -1
  98. data/lib/jsapi/status/base.rb +35 -0
  99. data/lib/jsapi/status/code.rb +113 -0
  100. data/lib/jsapi/status/default.rb +16 -0
  101. data/lib/jsapi/status/range.rb +35 -0
  102. data/lib/jsapi/status.rb +37 -0
  103. data/lib/jsapi/version.rb +1 -1
  104. data/lib/jsapi.rb +3 -3
  105. metadata +36 -10
  106. data/lib/jsapi/controller/parameters_invalid.rb +0 -27
  107. data/lib/jsapi/dsl/callback.rb +0 -21
  108. data/lib/jsapi/dsl/error.rb +0 -36
  109. data/lib/jsapi/invalid_argument_error.rb +0 -12
  110. data/lib/jsapi/invalid_value_error.rb +0 -12
  111. data/lib/jsapi/invalid_value_helper.rb +0 -17
  112. data/lib/jsapi/meta/model/type_caster.rb +0 -50
  113. data/lib/jsapi/meta/schema/delegator.rb +0 -26
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jsapi
4
+ module Meta
5
+ module Model
6
+ # Wraps a meta model
7
+ class Wrapper < SimpleDelegator
8
+ attr_reader :definitions
9
+
10
+ def initialize(model, definitions)
11
+ super(model.resolve(definitions))
12
+ @definitions = definitions
13
+ end
14
+
15
+ def ==(other) # :nodoc:
16
+ other.is_a?(self.class) &&
17
+ __getobj__ == other.__getobj__
18
+ end
19
+
20
+ def inspect # :nodoc:
21
+ "#<#{self.class.name} #{super}>"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'model/type_caster'
4
3
  require_relative 'model/attributes'
5
4
  require_relative 'model/base'
6
5
  require_relative 'model/reference'
6
+ require_relative 'model/wrapper'
7
+ require_relative 'model/wrappable'
@@ -36,7 +36,7 @@ module Jsapi
36
36
 
37
37
  ##
38
38
  # :attr: scopes
39
- # The hash containing the scopes.
39
+ # The scopes. Maps strings to Scope objects.
40
40
  attribute :scopes, { String => Scope }
41
41
 
42
42
  ##
@@ -11,12 +11,11 @@ module Jsapi
11
11
  private
12
12
 
13
13
  def with_openapi_extensions(keywords = {})
14
- keywords.merge!(
15
- openapi_extensions.transform_keys do |key|
16
- "x-#{key}".to_sym
17
- end
18
- ) if openapi_extensions.present?
19
-
14
+ if openapi_extensions.present?
15
+ keywords.merge!(
16
+ openapi_extensions.transform_keys { |key| "x-#{key}" }
17
+ )
18
+ end
20
19
  keywords.compact!
21
20
  keywords
22
21
  end
@@ -6,9 +6,9 @@ module Jsapi
6
6
  class Version
7
7
  include Comparable
8
8
 
9
- # Creates an \OpenAPI version from +version+.
9
+ # Transforms +version+ to an instance of this class.
10
10
  #
11
- # Raises an +ArgumentError+ if +version+ isn`t supported.
11
+ # Raises an +ArgumentError+ if +version+ could not be transformed.
12
12
  def self.from(version)
13
13
  return version if version.is_a?(Version)
14
14
 
@@ -48,13 +48,25 @@ module Jsapi
48
48
  minor <=> other.minor
49
49
  end
50
50
 
51
- def inspect
51
+ def inspect # :nodoc:
52
52
  "<#{self.class.name} #{self}>"
53
53
  end
54
54
 
55
55
  def to_s # :nodoc:
56
- "#{major}.#{minor}"
56
+ @to_s ||=
57
+ case [major, minor]
58
+ when [3, 0]
59
+ '3.0.4'
60
+ when [3, 1]
61
+ '3.1.2'
62
+ when [3, 2]
63
+ '3.2.0'
64
+ else
65
+ "#{major}.#{minor}"
66
+ end
57
67
  end
68
+
69
+ alias as_json to_s
58
70
  end
59
71
  end
60
72
  end
@@ -6,14 +6,101 @@ module Jsapi
6
6
  class Operation < Model::Base
7
7
  include OpenAPI::Extensions
8
8
 
9
+ class Wrapper < Model::Wrapper
10
+ # Returns the most appropriate response for +status_code+.
11
+ def find_response(status_code)
12
+ status_code = Status::Code.from(status_code)
13
+
14
+ responses.find do |status, _response|
15
+ status.match?(status_code)
16
+ end&.second
17
+ end
18
+
19
+ def full_path # :nodoc:
20
+ @full_path ||= super
21
+ end
22
+
23
+ ##
24
+ # :attr_reader: model
25
+ # The model class of the wrapped operation or the default model class
26
+ # for the path.
27
+
28
+ # -
29
+ def model
30
+ return @model if defined? @model
31
+
32
+ @model = super || definitions.common_model(full_path)
33
+ end
34
+
35
+ ##
36
+ # :attr_reader: parameters
37
+ # The parameters of the wrapped operation in combination with the
38
+ # parameters applying to all operations in the path.
39
+
40
+ # -
41
+ def parameters
42
+ @parameters ||=
43
+ (definitions.common_parameters(full_path)&.merge(super) || super)
44
+ .transform_values { |parameter| Parameter.wrap(parameter, definitions) }
45
+ end
46
+
47
+ ##
48
+ # :attr_reader: request_body
49
+ # The request body of the wrapped operation or the default request
50
+ # body for the path.
51
+
52
+ # -
53
+ def request_body
54
+ return @request_body if defined? @request_body
55
+
56
+ @request_body = RequestBody.wrap(
57
+ (super || definitions.common_request_body(full_path)),
58
+ definitions
59
+ )
60
+ end
61
+
62
+ ##
63
+ # :attr_reader: responses
64
+ # The responses of the wrapped operation in combination with the
65
+ # responses applying to all operations in the path.
66
+
67
+ # -
68
+ def responses
69
+ @responses ||=
70
+ (definitions.common_responses(full_path)&.merge(super) || super)
71
+ .transform_values { |response| Response.wrap(response, definitions) }
72
+ .sort_by { |status, _response| status }
73
+ .to_h
74
+ end
75
+
76
+ ##
77
+ # :attr_reader: security_requirements
78
+ # The security requirements of the wrapped operation in combination
79
+ # with the security requirements applying to all operations in the
80
+ # path or the default security requirements.
81
+
82
+ # -
83
+ def security_requirements
84
+ return @security_requirements if defined? @security_requirements
85
+
86
+ @security_requirements =
87
+ [definitions.common_security_requirements(full_path), super]
88
+ .compact.presence&.flatten ||
89
+ definitions.default_security_requirements
90
+ end
91
+ end
92
+
93
+ include Model::Wrappable
94
+
9
95
  ##
10
96
  # :attr: callbacks
11
- # The Callback objects. Applies to \OpenAPI 3.0 and higher.
97
+ # The callbacks that can be triggered by the operation. Maps strings
98
+ # to Callback objects or references.
12
99
  attribute :callbacks, { String => Callback }
13
100
 
14
101
  ##
15
102
  # :attr: deprecated
16
- # Specifies whether or not the operation is deprecated.
103
+ # Specifies whether the operation is marked as deprecated.
17
104
  attribute :deprecated, values: [true, false]
18
105
 
19
106
  ##
@@ -23,7 +110,9 @@ module Jsapi
23
110
 
24
111
  ##
25
112
  # :attr: external_docs
26
- # The ExternalDocumentation object.
113
+ # The additional external documentation for this operation.
114
+ #
115
+ # See ExternalDocumentation for further information.
27
116
  attribute :external_docs, ExternalDocumentation
28
117
 
29
118
  ##
@@ -33,8 +122,8 @@ module Jsapi
33
122
 
34
123
  ##
35
124
  # :attr: model
36
- # The model class to access top-level parameters by, Jsapi::Model::Base by default.
37
- attribute :model, Class, default: Jsapi::Model::Base
125
+ # The model class to access top-level parameters by.
126
+ attribute :model, Class
38
127
 
39
128
  ##
40
129
  # :attr_reader: name
@@ -43,7 +132,8 @@ module Jsapi
43
132
 
44
133
  ##
45
134
  # :attr: parameters
46
- # The parameters of the operation.
135
+ # The parameters of the operation. Maps parameter names to Parameter
136
+ # objects or references.
47
137
  attribute :parameters, { String => Parameter }, accessors: %i[reader writer]
48
138
 
49
139
  ##
@@ -58,17 +148,19 @@ module Jsapi
58
148
 
59
149
  ##
60
150
  # :attr: request_body
61
- # The request body of the operation.
151
+ # The request body of the operation as a RequestBody object or reference.
62
152
  attribute :request_body, RequestBody
63
153
 
64
154
  ##
65
155
  # :attr: responses
66
- # The responses of the operation.
67
- attribute :responses, { String => Response }, default_key: 'default'
156
+ # The responses that can be produced by the operation. Maps instances of
157
+ # Status::Base to Response objects or references.
158
+ attribute :responses, { Status => Response }, default_key: Status::DEFAULT
68
159
 
69
160
  ##
70
161
  # :attr: schemes
71
- # The transfer protocols supported by the operation. Possible values are:
162
+ # The transfer protocols supported by the operation. Can contain one or
163
+ # more of:
72
164
  #
73
165
  # - <code>"http"</code>
74
166
  # - <code>"https"</code>
@@ -80,14 +172,20 @@ module Jsapi
80
172
 
81
173
  ##
82
174
  # :attr: security_requirements
83
- # The SecurityRequirement objects.
84
- attribute :security_requirements, [SecurityRequirement]
175
+ # The security requirements that override the top-level security requirements.
176
+ #
177
+ # See SecurityRequirement for further information.
178
+ attribute :security_requirements, [SecurityRequirement], default: :nil
85
179
 
86
180
  alias add_security add_security_requirement
87
181
 
88
182
  ##
89
183
  # :attr: servers
90
- # The Server objects. Applies to \OpenAPI 3.0 and higher.
184
+ # The servers providing the operation.
185
+ #
186
+ # Applies to \OpenAPI 3.0 and higher.
187
+ #
188
+ # See Server for further information.
91
189
  attribute :servers, [Server]
92
190
 
93
191
  ##
@@ -109,7 +207,11 @@ module Jsapi
109
207
  end
110
208
 
111
209
  def add_parameter(name, keywords = {}) # :nodoc:
112
- (@parameters ||= {})[name.to_s] = Parameter.new(name, keywords)
210
+ try_modify_attribute!(:parameters) do
211
+ name = name.to_s
212
+
213
+ (@parameters ||= {})[name.to_s] = Parameter.new(name, keywords)
214
+ end
113
215
  end
114
216
 
115
217
  # Returns the full path of the operation as a Pathname.
@@ -117,73 +219,77 @@ module Jsapi
117
219
  parent_path + path
118
220
  end
119
221
 
120
- # Returns the MIME type consumed by the operation.
121
- def consumes(definitions)
122
- request_body&.resolve(definitions)&.content_type
123
- end
124
-
125
- # Returns an array containing the MIME types produced by the operation.
126
- def produces(definitions)
127
- responses.values.filter_map do |response|
128
- response.resolve(definitions).content_type
129
- end.uniq.sort
130
- end
131
-
132
- # Merges the parameters of this operation and the common parameters of all
133
- # parent pathes and resolves them.
134
- def resolved_parameters(definitions)
135
- (definitions.path_parameters(full_path).presence&.merge(parameters) || parameters)
136
- .transform_values { |parameter| parameter.resolve(definitions) }
137
- end
138
-
139
222
  # Returns a hash representing the \OpenAPI operation object.
140
223
  def to_openapi(version, definitions)
141
224
  version = OpenAPI::Version.from(version)
225
+ full_path = self.full_path
226
+
227
+ responses = (
228
+ definitions.common_responses(full_path)&.merge(self.responses) ||
229
+ self.responses
230
+ ).reject do |status, response|
231
+ response.resolve_lazily(definitions).nodoc ||
232
+ version == OpenAPI::V2_0 && status.is_a?(Status::Range)
233
+ end
142
234
 
143
235
  with_openapi_extensions(
144
236
  operationId: name,
145
- tags: tags.presence,
237
+ tags:
238
+ [tags, definitions.common_tags(full_path)]
239
+ .compact.flatten.uniq.presence,
146
240
  summary: summary,
147
241
  description: description,
148
242
  externalDocs: external_docs&.to_openapi,
149
- deprecated: deprecated?.presence,
150
- security: security_requirements.map(&:to_openapi).presence
151
- ).tap do |result|
152
- if version.major == 2
153
- if (consumes = consumes(definitions)).present?
154
- result[:consumes] = [consumes]
155
- end
156
- if (produces = produces(definitions)).present?
157
- result[:produces] = produces
158
- end
159
- result[:schemes] = schemes if schemes.present?
160
- elsif servers.present?
161
- result[:servers] = servers.map do |server|
162
- server.to_openapi(version)
163
- end
164
- end
165
- # Parameters (and request body)
166
- result[:parameters] = parameters.values.flat_map do |parameter|
167
- parameter.to_openapi_parameters(version, definitions)
168
- end
169
- if request_body
170
- if version.major == 2
171
- result[:parameters] << request_body.resolve(definitions).to_openapi_parameter
243
+ **if version == OpenAPI::V2_0
244
+ resolved_request_body =
245
+ (request_body || definitions.common_request_body(full_path))
246
+ &.resolve(definitions)
247
+ {
248
+ consumes:
249
+ [resolved_request_body&.default_media_range]
250
+ .compact.presence,
251
+ produces:
252
+ responses.values.filter_map do |response|
253
+ response.resolve(definitions).default_media_type
254
+ end.uniq.sort.presence,
255
+ schemes: schemes.presence,
256
+ parameters:
257
+ begin
258
+ params = parameters.values.flat_map do |parameter|
259
+ parameter.to_openapi_parameters(version, definitions)
260
+ end
261
+ if resolved_request_body
262
+ params << resolved_request_body.to_openapi_parameter
263
+ end
264
+ params
265
+ end
266
+ }
172
267
  else
173
- result[:request_body] = request_body.to_openapi(version)
174
- end
175
- end
176
- # Responses
177
- result[:responses] = responses.transform_values do |response|
178
- response.to_openapi(version, definitions)
179
- end
180
- # Callbacks
181
- if callbacks.present? && version.major > 2
182
- result[:callbacks] = callbacks.transform_values do |callback|
183
- callback.to_openapi(version, definitions)
184
- end
185
- end
186
- end
268
+ {
269
+ servers:
270
+ servers.map do |server|
271
+ server.to_openapi(version)
272
+ end.presence,
273
+ callbacks:
274
+ callbacks.transform_values do |callback|
275
+ callback.to_openapi(version, definitions)
276
+ end.presence,
277
+ parameters:
278
+ parameters.values.flat_map do |parameter|
279
+ parameter.to_openapi_parameters(version, definitions)
280
+ end,
281
+ request_body: request_body&.to_openapi(version)
282
+ }
283
+ end,
284
+ responses:
285
+ responses.transform_values do |response|
286
+ response.to_openapi(version, definitions)
287
+ end,
288
+ deprecated: deprecated?.presence,
289
+ security:
290
+ [security_requirements, definitions.common_security_requirements(full_path)]
291
+ .compact.presence&.flatten&.map(&:to_openapi)
292
+ )
187
293
  end
188
294
  end
189
295
  end
@@ -11,12 +11,12 @@ module Jsapi
11
11
 
12
12
  ##
13
13
  # :attr: content_type
14
- # The content type used to describe complex parameters in \OpenAPI 3.0 and higher.
15
- attribute :content_type, String
14
+ # The media type used to describe complex parameters in \OpenAPI 3.0 and higher.
15
+ attribute :content_type, Media::Type
16
16
 
17
17
  ##
18
18
  # :attr: deprecated
19
- # Specifies whether or not the parameter is deprecated.
19
+ # Specifies whether the parameter is marked as deprecated.
20
20
  attribute :deprecated, values: [true, false]
21
21
 
22
22
  ##
@@ -26,7 +26,7 @@ module Jsapi
26
26
 
27
27
  ##
28
28
  # :attr_reader: examples
29
- # The examples.
29
+ # The examples. Maps example names to Example objects or references.
30
30
  attribute :examples, { String => Example }, default_key: 'default'
31
31
 
32
32
  ##
@@ -95,7 +95,8 @@ module Jsapi
95
95
  schema.resolve(definitions),
96
96
  version,
97
97
  location: self.in,
98
- content_type: content_type || ('text/plain' if self.in == 'querystring'),
98
+ content_type: content_type ||
99
+ (Media::Type::TEXT_PLAIN if self.in == 'querystring'),
99
100
  description: description,
100
101
  required: required?,
101
102
  deprecated: deprecated?,
@@ -191,7 +192,10 @@ module Jsapi
191
192
  }
192
193
  else
193
194
  openapi_schema = schema.to_openapi(version).except(:deprecated)
194
- openapi_examples = examples&.transform_values(&:to_openapi).presence
195
+
196
+ openapi_examples = examples&.transform_values do |example|
197
+ example.to_openapi(version)
198
+ end.presence
195
199
  {
196
200
  deprecated: deprecated.presence,
197
201
  **if content_type.blank?
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jsapi
4
+ module Meta
5
+ module Parameter
6
+ class Wrapper < Model::Wrapper
7
+ def schema
8
+ @schema ||= Schema.wrap(super, definitions)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -2,10 +2,13 @@
2
2
 
3
3
  require_relative 'parameter/base'
4
4
  require_relative 'parameter/reference'
5
+ require_relative 'parameter/wrapper'
5
6
 
6
7
  module Jsapi
7
8
  module Meta
8
9
  module Parameter
10
+ include Model::Wrappable
11
+
9
12
  class << self
10
13
  # Creates a Base or Reference.
11
14
  def new(name, keywords = {})
@@ -6,35 +6,72 @@ module Jsapi
6
6
  class Path < Model::Base
7
7
  ##
8
8
  # :attr: description
9
- # The description that applies to all operations in this path.
9
+ # The common description for all operations in this path.
10
+ #
10
11
  # Applies to \OpenAPI 3.0 and higher.
11
12
  attribute :description, String
12
13
 
14
+ ##
15
+ # :attr: model
16
+ # The model class used by default for all operations in this path.
17
+ attribute :model, Class
18
+
13
19
  ##
14
20
  # :attr_reader: name
15
21
  # The relative path as a Pathname.
16
22
  attribute :name, Pathname, accessors: %i[reader]
17
23
 
24
+ ##
25
+ # :attr_reader: owner
26
+ attribute :owner, accessors: %i[reader]
27
+
18
28
  ##
19
29
  # :attr: parameters
20
- # The Parameter objects applicable for all operations in this path.
30
+ # The parameters that apply to all operations in this path. Maps
31
+ # parameter names to Parameter objects or references.
21
32
  attribute :parameters, { String => Parameter }, accessors: %i[reader writer]
22
33
 
23
34
  ##
24
- # :attr_reader: owner
25
- attribute :owner, accessors: %i[reader]
35
+ # :attr: request_body
36
+ # The RequestBody object or reference used by default by all operations
37
+ # in this path.
38
+ attribute :request_body, RequestBody
39
+
40
+ ##
41
+ # :attr: responses
42
+ # The responses that can be produced by all operations in this path.
43
+ # Maps instances of Status::Base to Response objects or references.
44
+ attribute :responses, { Status => Response }, default_key: Status::DEFAULT
45
+
46
+ ##
47
+ # :attr: security_requirements
48
+ # The security requirements that apply to all operations in this path.
49
+ #
50
+ # See SecurityRequirement for further information.
51
+ attribute :security_requirements, [SecurityRequirement], default: :nil
52
+
53
+ alias add_security add_security_requirement
54
+
55
+ ##
56
+ # :attr: servers
57
+ # The servers that apply by default to all operations in this path.
58
+ #
59
+ # Applies to \OpenAPI 3.0 and higher.
60
+ #
61
+ # See Server for further information.
62
+ attribute :servers, [Server]
26
63
 
27
64
  ##
28
65
  # :attr: summary
29
66
  # The summary that applies to all operations in this path.
67
+ #
30
68
  # Applies to \OpenAPI 3.0 and higher.
31
69
  attribute :summary, String
32
70
 
33
71
  ##
34
- # :attr: servers
35
- # The Server objects that applies to all operations in this path.
36
- # Applies to \OpenAPI 3.0 and higher.
37
- attribute :servers, [Server]
72
+ # :attr: tags
73
+ # The tags that apply to all operations in this path.
74
+ attribute :tags, [String]
38
75
 
39
76
  # Creates a new path with the given name and owner.
40
77
  def initialize(name, owner, keywords = {})
@@ -44,13 +81,22 @@ module Jsapi
44
81
  end
45
82
 
46
83
  def add_parameter(name, keywords = {}) # :nodoc:
47
- name = name.to_s
48
-
49
- Parameter.new(name, keywords).tap do |parameter|
50
- (@parameters ||= {})[name] = parameter
51
- @owner.try(:invalidate_path_parameters, self.name)
84
+ try_modify_attribute!(:parameters) do
85
+ name = name.to_s
86
+ (@parameters ||= {})[name] = Parameter.new(name, keywords)
52
87
  end
53
88
  end
89
+
90
+ def inspect(*attributes) # :nodoc:
91
+ super(*(attributes.presence || self.class.attribute_names).without(:owner))
92
+ end
93
+
94
+ protected
95
+
96
+ def attribute_changed(name)
97
+ @owner.try(:invalidate_path_attribute, self.name, name)
98
+ super
99
+ end
54
100
  end
55
101
  end
56
102
  end
@@ -5,10 +5,11 @@ module Jsapi
5
5
  # Represents a relative path name.
6
6
  class Pathname
7
7
  class << self
8
- # Creates a Pathname from +name+.
8
+ # Transforms +name+ to an instance of this class.
9
9
  def from(name)
10
10
  return name if name.is_a?(Pathname)
11
11
 
12
+ name = name[1..].presence if name&.match?(%r{\A/+\z})
12
13
  name.nil? ? new : new(name)
13
14
  end
14
15
  end
@@ -30,8 +31,8 @@ module Jsapi
30
31
 
31
32
  alias eql? ==
32
33
 
33
- # Creates a new Pathname by appending +other+ to +self+.
34
- # Returns +self+ if +other+ is nil.
34
+ # Creates a new Pathname by appending +other+ to itself.
35
+ # Returns itself if +other+ is nil.
35
36
  def +(other)
36
37
  return self if other.nil?
37
38
 
@@ -55,6 +56,8 @@ module Jsapi
55
56
  index.zero? && segment.blank? ? '//' : "/#{segment}"
56
57
  end&.join || '/'
57
58
  end
59
+
60
+ alias as_json to_s
58
61
  end
59
62
  end
60
63
  end
@@ -4,6 +4,16 @@ module Jsapi
4
4
  module Meta
5
5
  # Specifies a property
6
6
  class Property < Model::Base
7
+ class Wrapper < Model::Wrapper
8
+ delegate :additional_properties, :default_value, :items, to: :schema
9
+
10
+ def schema
11
+ @schema ||= Schema.wrap(super, definitions)
12
+ end
13
+ end
14
+
15
+ include Model::Wrappable
16
+
7
17
  delegate_missing_to :schema
8
18
 
9
19
  ##