Class: Jsapi::Meta::Definitions

Inherits:
Model::Base show all
Includes:
OpenAPI::Extensions
Defined in:
lib/jsapi/meta/definitions.rb

Constant Summary

Constants included from Model::Attributes

Model::Attributes::DEFAULT_ARRAY, Model::Attributes::DEFAULT_HASH

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from OpenAPI::Extensions

included

Methods inherited from Model::Base

#inspect, #merge!, #reference?, #resolve

Methods included from Model::Attributes

#attribute, #attribute_names

Constructor Details

#initialize(keywords = {}) ⇒ Definitions

Returns a new instance of Definitions.



133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/jsapi/meta/definitions.rb', line 133

def initialize(keywords = {})
  keywords = keywords.dup
  @owner = keywords.delete(:owner)
  @parent = keywords.delete(:parent)
  included = keywords.delete(:include)
  super(keywords)

  Array(included).each do |definitions|
    include(definitions)
  end
  @parent&.inherited(self)
end

Instance Attribute Details

#ownerObject (readonly)

The class to which this instance is assigned.



128
129
130
# File 'lib/jsapi/meta/definitions.rb', line 128

def owner
  @owner
end

#parentObject (readonly)

The Definitions instance from which this instance inherits.



131
132
133
# File 'lib/jsapi/meta/definitions.rb', line 131

def parent
  @parent
end

Instance Method Details

#add_operation(name, parent_path = nil, keywords = {}) ⇒ Object

:nodoc:



146
147
148
149
150
151
152
153
# File 'lib/jsapi/meta/definitions.rb', line 146

def add_operation(name, parent_path = nil, keywords = {}) # :nodoc:
  parent_path, keywords = nil, parent_path if parent_path.is_a?(Hash)

  name = name.nil? ? default_operation_name : name.to_s
  parent_path ||= default_operation_name unless keywords[:path].present?

  (@operations ||= {})[name] = Operation.new(name, parent_path, keywords)
end

#add_parameter(name, keywords = {}) ⇒ Object

:nodoc:



155
156
157
158
159
160
161
162
# File 'lib/jsapi/meta/definitions.rb', line 155

def add_parameter(name, keywords = {}) # :nodoc:
  name = name.to_s

  Parameter.new(name, keywords).tap do |parameter|
    (@parameters ||= {})[name] = parameter
    attribute_changed(:parameters)
  end
end

#add_path(name, keywords = {}) ⇒ Object

:nodoc:



164
165
166
167
# File 'lib/jsapi/meta/definitions.rb', line 164

def add_path(name, keywords = {}) # :nodoc:
  pathname = Pathname.from(name)
  (@paths ||= {})[pathname] ||= Path.new(pathname, self, keywords)
end

#ancestorsObject

Returns an array containing itself and all of the Definitions instances inherited/included.



171
172
173
174
175
176
177
# File 'lib/jsapi/meta/definitions.rb', line 171

def ancestors
  @ancestors ||= [self].tap do |ancestors|
    [@included_definitions, @parent].flatten.each do |definitions|
      ancestors.push(*definitions.ancestors) if definitions
    end
  end.uniq
end

#base_pathObject

:attr: base_path The base path of the API. Applies to OpenAPI 2.0.



11
# File 'lib/jsapi/meta/definitions.rb', line 11

attribute :base_path, Pathname

#callbacksObject

:attr: callbacks The reusable Callback objects. Applies to OpenAPI 3.0 and higher.



16
# File 'lib/jsapi/meta/definitions.rb', line 16

attribute :callbacks, { String => Callback }

#default_value(type, context: nil) ⇒ Object

Returns the default value for type within context.



180
181
182
# File 'lib/jsapi/meta/definitions.rb', line 180

def default_value(type, context: nil)
  objects.dig(:defaults, type.to_s)&.value(context: context)
end

#defaultsObject

:attr: defaults The Defaults.



21
# File 'lib/jsapi/meta/definitions.rb', line 21

attribute :defaults, { String => Defaults }, keys: Schema::TYPES

#examplesObject

:attr: examples The reusable Example objects. Applies to OpenAPI 3.0 and higher.



26
# File 'lib/jsapi/meta/definitions.rb', line 26

attribute :examples, { String => Example }

#external_docsObject

:attr: external_docs The ExternalDocumentation object.



31
# File 'lib/jsapi/meta/definitions.rb', line 31

attribute :external_docs, ExternalDocumentation

#find_operation(name = nil) ⇒ Object

Returns the operation with the specified name.



185
186
187
188
189
190
# File 'lib/jsapi/meta/definitions.rb', line 185

def find_operation(name = nil)
  return objects.dig(:operations, name.to_s) if name.present?

  # Return the one and only operation
  operations.values.first if operations.one?
end

#find_parameter(name) ⇒ Object

Returns the reusable parameter with the specified name.



193
194
195
# File 'lib/jsapi/meta/definitions.rb', line 193

def find_parameter(name)
  objects.dig(:parameters, name&.to_s)
end

#find_request_body(name) ⇒ Object

Returns the reusable request body with the specified name.



198
199
200
# File 'lib/jsapi/meta/definitions.rb', line 198

def find_request_body(name)
  objects.dig(:request_bodies, name&.to_s)
end

#find_response(name) ⇒ Object

Returns the reusable response with the specified name.



203
204
205
# File 'lib/jsapi/meta/definitions.rb', line 203

def find_response(name)
  objects.dig(:responses, name&.to_s)
end

#find_schema(name) ⇒ Object

Returns the reusable schema with the specified name.



208
209
210
# File 'lib/jsapi/meta/definitions.rb', line 208

def find_schema(name)
  objects.dig(:schemas, name&.to_s)
end

#headersObject

:attr: headers The reusable Header objects. Applies to OpenAPI 3.0 and higher.



36
# File 'lib/jsapi/meta/definitions.rb', line 36

attribute :headers, { String => Header }

#hostObject

:attr: host The host serving the API. Applies to OpenAPI 2.0.



41
# File 'lib/jsapi/meta/definitions.rb', line 41

attribute :host, String

#include(definitions) ⇒ Object

Includes definitions.



213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/jsapi/meta/definitions.rb', line 213

def include(definitions)
  if circular_dependency?(definitions)
    raise ArgumentError,
          'detected circular dependency between ' \
          "#{owner.inspect} and " \
          "#{definitions.owner.inspect}"
  end

  (@included_definitions ||= []) << definitions
  definitions.included(self)
  invalidate_ancestors
  self
end

#infoObject

:attr: info The Info object.



46
# File 'lib/jsapi/meta/definitions.rb', line 46

attribute :info, Info

#invalidate_path_parameters(pathname) ⇒ Object

Resets the memoized parameters for the given path.



228
229
230
231
232
233
# File 'lib/jsapi/meta/definitions.rb', line 228

def invalidate_path_parameters(pathname)
  pathname = Pathname.from(pathname)

  @path_parameters&.delete(pathname)
  each_descendant { |descendant| descendant.invalidate_path_parameters(pathname) }
end

#json_schema_document(name) ⇒ Object

Returns a hash representing the JSON Schema document for name.



236
237
238
239
240
241
242
# File 'lib/jsapi/meta/definitions.rb', line 236

def json_schema_document(name)
  find_schema(name)&.to_json_schema&.tap do |json_schema_document|
    if (schemas = objects[:schemas].except(name.to_s)).any?
      json_schema_document[:definitions] = schemas.transform_values(&:to_json_schema)
    end
  end
end

:attr: links The reusable Link objects. Applies to OpenAPI 3.0 and higher.



51
# File 'lib/jsapi/meta/definitions.rb', line 51

attribute :links, { String => Link }

#nameObject

:method: path_summary :args: pathname Returns the most accurate summary for the given path.



346
347
348
349
350
351
352
353
354
355
356
# File 'lib/jsapi/meta/definitions.rb', line 346

i[description servers summary].each do |name|
  define_method(:"path_#{name}") do |arg|
    Pathname.from(arg).ancestors.each do |pathname|
      ancestors.each do |ancestor|
        value = ancestor.path(pathname)&.public_send(name)
        return value if value.present?
      end
    end
    nil
  end
end

#on_rescue_callbacksObject

Returns the methods or procs to be called when rescuing an exception.



245
246
247
# File 'lib/jsapi/meta/definitions.rb', line 245

def on_rescue_callbacks
  objects[:on_rescues]
end

#on_rescuesObject

:attr: on_rescues The methods or procs to be called whenever an exception is rescued.



56
# File 'lib/jsapi/meta/definitions.rb', line 56

attribute :on_rescues, []

#openapi_document(version = nil) ⇒ Object

Returns a hash representing the OpenAPI document for version.

Raises an ArgumentError if version is not supported.



252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/jsapi/meta/definitions.rb', line 252

def openapi_document(version = nil)
  version = OpenAPI::Version.from(version)
  operations = objects[:operations].values

  openapi_paths = operations.group_by(&:full_path).to_h do |key, value|
    [
      key.to_s,
      OpenAPI::PathItem.new(
        value,
        description: path_description(key),
        parameters: path_parameters(key),
        summary: path_summary(key),
        servers: path_servers(key)
      ).to_openapi(version, self)
    ]
  end.presence

  openapi_objects = (
    i[external_docs info parameters responses schemas
       security_requirements security_schemes tags] +
    if version == OpenAPI::V2_0
      i[base_path host schemes]
    else
      i[callbacks examples headers links request_bodies servers]
    end
  ).index_with { |key| object_to_openapi(objects[key], version).presence }

  with_openapi_extensions(
    if version == OpenAPI::V2_0
      openapi_server = objects[:servers].first || default_server
      uri = URI(openapi_server.url) if openapi_server
      {
        # Order according to the OpenAPI specification 2.x
        swagger: '2.0',
        info: openapi_objects[:info],
        host: openapi_objects[:host] || uri&.hostname,
        basePath: openapi_objects[:base_path]&.to_s || uri&.path,
        schemes: openapi_objects[:schemes] || Array(uri&.scheme).presence,
        consumes: operations.filter_map do |operation|
          operation.consumes(self)
        end.uniq.sort.presence,
        produces: operations.flat_map do |operation|
          operation.produces(self).map(&:to_s)
        end.uniq.sort.presence,
        paths: openapi_paths,
        definitions: openapi_objects[:schemas],
        parameters: openapi_objects[:parameters],
        responses: openapi_objects[:responses],
        securityDefinitions: openapi_objects[:security_schemes]
      }
    else
      {
        # Order according to the OpenAPI specification 3.x
        openapi: version.to_s,
        info: openapi_objects[:info],
        servers:
          openapi_objects[:servers] ||
          [default_server&.to_openapi(version)].compact.presence,
        paths: openapi_paths,
        components: {
          schemas: openapi_objects[:schemas],
          responses: openapi_objects[:responses],
          parameters: openapi_objects[:parameters],
          examples: openapi_objects[:examples],
          requestBodies: openapi_objects[:request_bodies],
          headers: openapi_objects[:headers],
          securitySchemes: openapi_objects[:security_schemes],
          links: openapi_objects[:links],
          callbacks: openapi_objects[:callbacks]
        }.compact.presence
      }
    end.merge(
      security: openapi_objects[:security_requirements],
      tags: openapi_objects[:tags],
      externalDocs: openapi_objects[:external_docs]
    ).compact
  )
end

#operationsObject

:attr: operations The Operation objects.



61
# File 'lib/jsapi/meta/definitions.rb', line 61

attribute :operations, { String => Operation }, accessors: i[reader writer]

#parametersObject

:attr: parameters The reusable Parameter objects.



66
# File 'lib/jsapi/meta/definitions.rb', line 66

attribute :parameters, { String => Parameter }, accessors: i[reader writer]

#path_parameters(arg) ⇒ Object

Returns a hash containing the Parameter objects that are applicable to all operations in the given path. :args: pathname



361
362
363
364
365
366
367
# File 'lib/jsapi/meta/definitions.rb', line 361

def path_parameters(arg)
  arg = Pathname.from(arg || '')

  (@path_parameters ||= {})[arg] ||= arg.ancestors.flat_map do |pathname|
    ancestors.filter_map { |ancestor| ancestor.path(pathname)&.parameters }
  end.reduce(&:reverse_merge) || {}
end

#pathsObject

:attr: paths The Path objects.



71
# File 'lib/jsapi/meta/definitions.rb', line 71

attribute :paths, { Pathname => Path }, accessors: i[reader writer]

#request_bodiesObject

:attr: request_bodies The reusable RequestBody objects.



81
# File 'lib/jsapi/meta/definitions.rb', line 81

attribute :request_bodies, { String => RequestBody }

#rescue_handler_for(exception) ⇒ Object

Returns the first RescueHandler to handle exception, or nil if no one could be found.



370
371
372
# File 'lib/jsapi/meta/definitions.rb', line 370

def rescue_handler_for(exception)
  objects[:rescue_handlers].find { |r| r.match?(exception) }
end

#rescue_handlersObject

:attr: rescue_handlers The RescueHandler objects.



76
# File 'lib/jsapi/meta/definitions.rb', line 76

attribute :rescue_handlers, [RescueHandler]

#responsesObject

:attr: responses The reusable Response objects.



86
# File 'lib/jsapi/meta/definitions.rb', line 86

attribute :responses, { String => Response }

#schemasObject

:attr: schemas The reusable Schema objects.



91
# File 'lib/jsapi/meta/definitions.rb', line 91

attribute :schemas, { String => Schema }

#schemesObject

:attr: schemes The array of transfer protocols supported by the API. Possible values are:

  • "http"

  • "https"

  • "ws"

  • "wss"

Applies to OpenAPI 2.0.



103
# File 'lib/jsapi/meta/definitions.rb', line 103

attribute :schemes, [String], values: %w[http https ws wss]

#security_requirementsObject

:attr: security_requirements The array of SecurityRequirement objects.



108
# File 'lib/jsapi/meta/definitions.rb', line 108

attribute :security_requirements, [SecurityRequirement]

#security_schemesObject

:attr: security_schemes The SecurityScheme objects.



115
# File 'lib/jsapi/meta/definitions.rb', line 115

attribute :security_schemes, { String => SecurityScheme }

#serversObject

:attr: servers The array of Server objects. Applies to OpenAPI 3.0 and higher.



120
# File 'lib/jsapi/meta/definitions.rb', line 120

attribute :servers, [Server]

#tagsObject

:attr: tags The array of Tag objects.



125
# File 'lib/jsapi/meta/definitions.rb', line 125

attribute :tags, [Tag]