jsapi 0.1.1
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 +7 -0
- data/lib/jsapi/controller/base.rb +21 -0
- data/lib/jsapi/controller/error_result.rb +21 -0
- data/lib/jsapi/controller/methods.rb +144 -0
- data/lib/jsapi/controller/parameters.rb +86 -0
- data/lib/jsapi/controller/parameters_invalid.rb +25 -0
- data/lib/jsapi/controller/response.rb +84 -0
- data/lib/jsapi/controller.rb +13 -0
- data/lib/jsapi/dsl/callbacks.rb +32 -0
- data/lib/jsapi/dsl/class_methods.rb +85 -0
- data/lib/jsapi/dsl/definitions.rb +102 -0
- data/lib/jsapi/dsl/error.rb +38 -0
- data/lib/jsapi/dsl/examples.rb +30 -0
- data/lib/jsapi/dsl/node.rb +62 -0
- data/lib/jsapi/dsl/openapi/callback.rb +23 -0
- data/lib/jsapi/dsl/openapi/root.rb +12 -0
- data/lib/jsapi/dsl/openapi.rb +4 -0
- data/lib/jsapi/dsl/operation.rb +118 -0
- data/lib/jsapi/dsl/parameter.rb +10 -0
- data/lib/jsapi/dsl/request_body.rb +10 -0
- data/lib/jsapi/dsl/response.rb +33 -0
- data/lib/jsapi/dsl/schema.rb +87 -0
- data/lib/jsapi/dsl.rb +24 -0
- data/lib/jsapi/json/array.rb +35 -0
- data/lib/jsapi/json/boolean.rb +17 -0
- data/lib/jsapi/json/integer.rb +15 -0
- data/lib/jsapi/json/null.rb +27 -0
- data/lib/jsapi/json/number.rb +15 -0
- data/lib/jsapi/json/object.rb +53 -0
- data/lib/jsapi/json/string.rb +29 -0
- data/lib/jsapi/json/value.rb +47 -0
- data/lib/jsapi/json.rb +41 -0
- data/lib/jsapi/meta/attributes/class_methods.rb +112 -0
- data/lib/jsapi/meta/attributes/type_caster.rb +48 -0
- data/lib/jsapi/meta/attributes.rb +4 -0
- data/lib/jsapi/meta/base.rb +41 -0
- data/lib/jsapi/meta/base_reference.rb +33 -0
- data/lib/jsapi/meta/definitions.rb +226 -0
- data/lib/jsapi/meta/example/model.rb +44 -0
- data/lib/jsapi/meta/example/reference.rb +15 -0
- data/lib/jsapi/meta/example.rb +19 -0
- data/lib/jsapi/meta/existence.rb +69 -0
- data/lib/jsapi/meta/invalid_argument_error.rb +11 -0
- data/lib/jsapi/meta/openapi/callback/model.rb +36 -0
- data/lib/jsapi/meta/openapi/callback/reference.rb +16 -0
- data/lib/jsapi/meta/openapi/callback.rb +21 -0
- data/lib/jsapi/meta/openapi/contact.rb +34 -0
- data/lib/jsapi/meta/openapi/external_documentation.rb +28 -0
- data/lib/jsapi/meta/openapi/info.rb +52 -0
- data/lib/jsapi/meta/openapi/license.rb +28 -0
- data/lib/jsapi/meta/openapi/link/model.rb +48 -0
- data/lib/jsapi/meta/openapi/link/reference.rb +16 -0
- data/lib/jsapi/meta/openapi/link.rb +21 -0
- data/lib/jsapi/meta/openapi/oauth_flow.rb +50 -0
- data/lib/jsapi/meta/openapi/root.rb +134 -0
- data/lib/jsapi/meta/openapi/security_requirement.rb +27 -0
- data/lib/jsapi/meta/openapi/security_scheme/api_key.rb +38 -0
- data/lib/jsapi/meta/openapi/security_scheme/base.rb +16 -0
- data/lib/jsapi/meta/openapi/security_scheme/http/basic.rb +31 -0
- data/lib/jsapi/meta/openapi/security_scheme/http/bearer.rb +37 -0
- data/lib/jsapi/meta/openapi/security_scheme/http/other.rb +37 -0
- data/lib/jsapi/meta/openapi/security_scheme/http.rb +31 -0
- data/lib/jsapi/meta/openapi/security_scheme/oauth2.rb +47 -0
- data/lib/jsapi/meta/openapi/security_scheme/open_id_connect.rb +33 -0
- data/lib/jsapi/meta/openapi/security_scheme.rb +51 -0
- data/lib/jsapi/meta/openapi/server.rb +34 -0
- data/lib/jsapi/meta/openapi/server_variable.rb +34 -0
- data/lib/jsapi/meta/openapi/tag.rb +34 -0
- data/lib/jsapi/meta/openapi/version.rb +41 -0
- data/lib/jsapi/meta/openapi.rb +16 -0
- data/lib/jsapi/meta/operation.rb +186 -0
- data/lib/jsapi/meta/parameter/model.rb +170 -0
- data/lib/jsapi/meta/parameter/reference.rb +30 -0
- data/lib/jsapi/meta/parameter.rb +19 -0
- data/lib/jsapi/meta/property.rb +62 -0
- data/lib/jsapi/meta/reference_error.rb +12 -0
- data/lib/jsapi/meta/request_body/model.rb +65 -0
- data/lib/jsapi/meta/request_body/reference.rb +14 -0
- data/lib/jsapi/meta/request_body.rb +19 -0
- data/lib/jsapi/meta/rescue_handler.rb +26 -0
- data/lib/jsapi/meta/response/model.rb +72 -0
- data/lib/jsapi/meta/response/reference.rb +17 -0
- data/lib/jsapi/meta/response.rb +19 -0
- data/lib/jsapi/meta/schema/array.rb +42 -0
- data/lib/jsapi/meta/schema/base.rb +146 -0
- data/lib/jsapi/meta/schema/boolean.rb +9 -0
- data/lib/jsapi/meta/schema/boundary.rb +37 -0
- data/lib/jsapi/meta/schema/conversion.rb +28 -0
- data/lib/jsapi/meta/schema/delegator.rb +26 -0
- data/lib/jsapi/meta/schema/discriminator.rb +36 -0
- data/lib/jsapi/meta/schema/integer.rb +9 -0
- data/lib/jsapi/meta/schema/number.rb +9 -0
- data/lib/jsapi/meta/schema/numeric.rb +56 -0
- data/lib/jsapi/meta/schema/object.rb +85 -0
- data/lib/jsapi/meta/schema/reference.rb +38 -0
- data/lib/jsapi/meta/schema/string.rb +58 -0
- data/lib/jsapi/meta/schema/validation/base.rb +29 -0
- data/lib/jsapi/meta/schema/validation/enum.rb +26 -0
- data/lib/jsapi/meta/schema/validation/max_items.rb +26 -0
- data/lib/jsapi/meta/schema/validation/max_length.rb +26 -0
- data/lib/jsapi/meta/schema/validation/maximum.rb +51 -0
- data/lib/jsapi/meta/schema/validation/min_items.rb +26 -0
- data/lib/jsapi/meta/schema/validation/min_length.rb +26 -0
- data/lib/jsapi/meta/schema/validation/minimum.rb +51 -0
- data/lib/jsapi/meta/schema/validation/multiple_of.rb +24 -0
- data/lib/jsapi/meta/schema/validation/pattern.rb +30 -0
- data/lib/jsapi/meta/schema/validation.rb +12 -0
- data/lib/jsapi/meta/schema.rb +61 -0
- data/lib/jsapi/meta.rb +23 -0
- data/lib/jsapi/model/attributes.rb +22 -0
- data/lib/jsapi/model/base.rb +34 -0
- data/lib/jsapi/model/error.rb +15 -0
- data/lib/jsapi/model/errors.rb +51 -0
- data/lib/jsapi/model/naming.rb +28 -0
- data/lib/jsapi/model/nestable.rb +37 -0
- data/lib/jsapi/model/nested_error.rb +54 -0
- data/lib/jsapi/model/validations.rb +27 -0
- data/lib/jsapi/model.rb +15 -0
- data/lib/jsapi/version.rb +8 -0
- data/lib/jsapi.rb +8 -0
- metadata +162 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'parameter/model'
|
4
|
+
require_relative 'parameter/reference'
|
5
|
+
|
6
|
+
module Jsapi
|
7
|
+
module Meta
|
8
|
+
module Parameter
|
9
|
+
class << self
|
10
|
+
# Creates a new parameter model or reference.
|
11
|
+
def new(name, keywords = {})
|
12
|
+
return Reference.new(keywords) if keywords.key?(:ref)
|
13
|
+
|
14
|
+
Model.new(name, keywords)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
class Property < Base
|
6
|
+
##
|
7
|
+
# :attr_reader: name
|
8
|
+
# The name of the property.
|
9
|
+
attribute :name, writer: false
|
10
|
+
|
11
|
+
##
|
12
|
+
# :attr: read_only
|
13
|
+
attribute :read_only, values: [true, false]
|
14
|
+
|
15
|
+
##
|
16
|
+
# :attr_reader: schema
|
17
|
+
# The Schema of the parameter.
|
18
|
+
attribute :schema, writer: false
|
19
|
+
|
20
|
+
##
|
21
|
+
# :attr: source
|
22
|
+
# The alternative method to read a property value when serializing
|
23
|
+
# an object.
|
24
|
+
attribute :source, Symbol
|
25
|
+
|
26
|
+
##
|
27
|
+
# :attr: write_only
|
28
|
+
attribute :write_only, values: [true, false]
|
29
|
+
|
30
|
+
delegate_missing_to :schema
|
31
|
+
|
32
|
+
# Creates a new property.
|
33
|
+
#
|
34
|
+
# Raises an +ArgumentError+ if +name+ is blank.
|
35
|
+
def initialize(name, keywords = {})
|
36
|
+
raise ArgumentError, "property name can't be blank" if name.blank?
|
37
|
+
|
38
|
+
keywords = keywords.dup
|
39
|
+
super(keywords.extract!(:read_only, :source, :write_only))
|
40
|
+
|
41
|
+
@name = name.to_s
|
42
|
+
@schema = Schema.new(keywords)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns true if the level of existence is greater than or equal to
|
46
|
+
# +ALLOW_NIL+, false otherwise.
|
47
|
+
def required?
|
48
|
+
schema.existence >= Existence::ALLOW_NIL
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns a hash representing the \OpenAPI schema object.
|
52
|
+
def to_openapi(version)
|
53
|
+
version = OpenAPI::Version.from(version)
|
54
|
+
|
55
|
+
schema.to_openapi(version).tap do |hash|
|
56
|
+
hash[:readOnly] = true if read_only?
|
57
|
+
hash[:writeOnly] = true if write_only? && version.major > 2
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
module RequestBody
|
6
|
+
class Model < Base
|
7
|
+
##
|
8
|
+
# :attr: description
|
9
|
+
# The optional description of the request body.
|
10
|
+
attribute :description, String
|
11
|
+
|
12
|
+
##
|
13
|
+
# :attr_reader: examples
|
14
|
+
# The optional examples.
|
15
|
+
attribute :examples, { String => Example }, default_key: 'default'
|
16
|
+
|
17
|
+
##
|
18
|
+
# :attr_reader: schema
|
19
|
+
# The Schema of the parameter.
|
20
|
+
attribute :schema, writer: false
|
21
|
+
|
22
|
+
delegate_missing_to :schema
|
23
|
+
|
24
|
+
def initialize(keywords = {})
|
25
|
+
keywords = keywords.dup
|
26
|
+
super(keywords.extract!(:description, :examples))
|
27
|
+
|
28
|
+
add_example(value: keywords.delete(:example)) if keywords.key?(:example)
|
29
|
+
|
30
|
+
@schema = Schema.new(keywords)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns true if the level of existence is greater than or equal to
|
34
|
+
# +ALLOW_NIL+, false otherwise.
|
35
|
+
def required?
|
36
|
+
schema.existence >= Existence::ALLOW_NIL
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns a hash representing the \OpenAPI 2.0 parameter object.
|
40
|
+
def to_openapi_parameter
|
41
|
+
{
|
42
|
+
name: 'body',
|
43
|
+
in: 'body',
|
44
|
+
description: description,
|
45
|
+
required: required?
|
46
|
+
}.merge(schema.to_openapi('2.0')).compact
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns a hash representing the \OpenAPI 3.x request body object.
|
50
|
+
def to_openapi(version)
|
51
|
+
{
|
52
|
+
description: description,
|
53
|
+
content: {
|
54
|
+
'application/json' => {
|
55
|
+
schema: schema.to_openapi(version),
|
56
|
+
examples: examples&.transform_values(&:to_openapi)
|
57
|
+
}.compact
|
58
|
+
},
|
59
|
+
required: required?
|
60
|
+
}.compact
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
module RequestBody
|
6
|
+
class Reference < BaseReference
|
7
|
+
# Returns a hash representing the \OpenAPI reference object.
|
8
|
+
def to_openapi(*)
|
9
|
+
{ '$ref': "#/components/requestBodies/#{ref}" }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'request_body/model'
|
4
|
+
require_relative 'request_body/reference'
|
5
|
+
|
6
|
+
module Jsapi
|
7
|
+
module Meta
|
8
|
+
module RequestBody
|
9
|
+
class << self
|
10
|
+
# Creates a new request body model or reference.
|
11
|
+
def new(keywords = {})
|
12
|
+
return Reference.new(keywords) if keywords.key?(:ref)
|
13
|
+
|
14
|
+
Model.new(keywords)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
class RescueHandler
|
6
|
+
attr_reader :status
|
7
|
+
|
8
|
+
def initialize(klass, status: nil)
|
9
|
+
unless klass.is_a?(Class) && klass.ancestors.include?(StandardError)
|
10
|
+
raise ArgumentError, "#{klass.inspect} must be a standard error class"
|
11
|
+
end
|
12
|
+
|
13
|
+
@klass = klass
|
14
|
+
@status = status || 'default'
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect # :nodoc:
|
18
|
+
"#<#{self.class.name} class: #{@klass}, status: #{@status.inspect}>"
|
19
|
+
end
|
20
|
+
|
21
|
+
def match?(exception)
|
22
|
+
exception.is_a?(@klass)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
module Response
|
6
|
+
class Model < Base
|
7
|
+
##
|
8
|
+
# :attr: description
|
9
|
+
# The optional description of the response.
|
10
|
+
attribute :description, String
|
11
|
+
|
12
|
+
##
|
13
|
+
# :attr: examples
|
14
|
+
# The optional examples.
|
15
|
+
attribute :examples, { String => Example }, default_key: 'default'
|
16
|
+
|
17
|
+
##
|
18
|
+
# :attr: links
|
19
|
+
# The optional OpenAPI::Link objects.
|
20
|
+
attribute :links, { String => OpenAPI::Link }
|
21
|
+
|
22
|
+
##
|
23
|
+
# :attr: locale
|
24
|
+
# The locale used when rendering a response.
|
25
|
+
attribute :locale, Symbol
|
26
|
+
|
27
|
+
##
|
28
|
+
# :attr_reader: schema
|
29
|
+
# The Schema of the parameter.
|
30
|
+
attribute :schema, writer: false
|
31
|
+
|
32
|
+
delegate_missing_to :schema
|
33
|
+
|
34
|
+
def initialize(keywords = {})
|
35
|
+
keywords = keywords.dup
|
36
|
+
super(keywords.extract!(:description, :examples, :locale))
|
37
|
+
|
38
|
+
add_example(value: keywords.delete(:example)) if keywords.key?(:example)
|
39
|
+
|
40
|
+
@schema = Schema.new(**keywords)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns a hash representing the \OpenAPI response object.
|
44
|
+
def to_openapi(version, definitions)
|
45
|
+
version = OpenAPI::Version.from(version)
|
46
|
+
if version.major == 2
|
47
|
+
{
|
48
|
+
description: description,
|
49
|
+
schema: schema.to_openapi(version),
|
50
|
+
examples: (
|
51
|
+
if (example = examples&.values&.first).present?
|
52
|
+
{ 'application/json' => example.resolve(definitions).value }
|
53
|
+
end
|
54
|
+
)
|
55
|
+
}
|
56
|
+
else
|
57
|
+
{
|
58
|
+
description: description,
|
59
|
+
content: {
|
60
|
+
'application/json' => {
|
61
|
+
schema: schema.to_openapi(version),
|
62
|
+
examples: examples&.transform_values(&:to_openapi)
|
63
|
+
}.compact
|
64
|
+
},
|
65
|
+
links: links&.transform_values(&:to_openapi)
|
66
|
+
}
|
67
|
+
end.compact
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
module Response
|
6
|
+
class Reference < BaseReference
|
7
|
+
# Returns a hash representing the \OpenAPI reference object.
|
8
|
+
def to_openapi(version, *)
|
9
|
+
version = OpenAPI::Version.from(version)
|
10
|
+
path = version.major == 2 ? 'responses' : 'components/responses'
|
11
|
+
|
12
|
+
{ '$ref': "#/#{path}/#{ref}" }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'response/model'
|
4
|
+
require_relative 'response/reference'
|
5
|
+
|
6
|
+
module Jsapi
|
7
|
+
module Meta
|
8
|
+
module Response
|
9
|
+
class << self
|
10
|
+
# Creates a new response model or reference.
|
11
|
+
def new(keywords = {})
|
12
|
+
return Reference.new(keywords) if keywords.key?(:ref)
|
13
|
+
|
14
|
+
Model.new(keywords)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
module Schema
|
6
|
+
class Array < Base
|
7
|
+
##
|
8
|
+
# :attr: items
|
9
|
+
# The Schema defining the kind of items.
|
10
|
+
attribute :items, Schema
|
11
|
+
|
12
|
+
##
|
13
|
+
# :attr: max_items
|
14
|
+
# The maximum length of an array.
|
15
|
+
attribute :max_items, writer: false
|
16
|
+
|
17
|
+
##
|
18
|
+
# :attr: min_items
|
19
|
+
# The minimum length of an array.
|
20
|
+
attribute :min_items, writer: false
|
21
|
+
|
22
|
+
def max_items=(value) # :nodoc:
|
23
|
+
add_validation('max_items', Validation::MaxItems.new(value))
|
24
|
+
@max_items = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def min_items=(value) # :nodoc:
|
28
|
+
add_validation('min_items', Validation::MinItems.new(value))
|
29
|
+
@min_items = value
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_json_schema # :nodoc:
|
33
|
+
super.merge(items: items&.to_json_schema || {})
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_openapi(version) # :nodoc:
|
37
|
+
super.merge(items: items&.to_openapi(version) || {})
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
module Schema
|
6
|
+
class Base < Meta::Base
|
7
|
+
TYPES = %w[array boolean integer number object string].freeze # :nodoc:
|
8
|
+
|
9
|
+
TYPES.each do |type|
|
10
|
+
define_method("#{type}?") { self.type == type }
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# :attr: default
|
15
|
+
# The optional default value.
|
16
|
+
attribute :default
|
17
|
+
|
18
|
+
##
|
19
|
+
# :attr: deprecated
|
20
|
+
# Specifies whether or not the schema is deprecated.
|
21
|
+
attribute :deprecated, values: [true, false]
|
22
|
+
|
23
|
+
##
|
24
|
+
# :attr: description
|
25
|
+
# The optional description of the schema.
|
26
|
+
attribute :description, ::String
|
27
|
+
|
28
|
+
##
|
29
|
+
# :attr: enum
|
30
|
+
# The allowed values.
|
31
|
+
attribute :enum, writer: false
|
32
|
+
|
33
|
+
##
|
34
|
+
# :attr: examples
|
35
|
+
# The optional examples.
|
36
|
+
attribute :examples, [::Object]
|
37
|
+
|
38
|
+
##
|
39
|
+
# :attr: external_docs
|
40
|
+
# The optional OpenAPI::ExternalDocumentation object.
|
41
|
+
attribute :external_docs, OpenAPI::ExternalDocumentation
|
42
|
+
|
43
|
+
##
|
44
|
+
# :attr: existence
|
45
|
+
# The level of Existence. The default level of existence
|
46
|
+
# is +ALLOW_OMITTED+.
|
47
|
+
attribute :existence, Existence, default: Existence::ALLOW_OMITTED
|
48
|
+
|
49
|
+
##
|
50
|
+
# :attr: title
|
51
|
+
# The optional title of the schema.
|
52
|
+
attribute :title, String
|
53
|
+
|
54
|
+
##
|
55
|
+
# :attr_reader: type
|
56
|
+
# The type of the schema as a string.
|
57
|
+
|
58
|
+
# The validations.
|
59
|
+
attr_reader :validations
|
60
|
+
|
61
|
+
# Creates a new schema.
|
62
|
+
def initialize(keywords = {})
|
63
|
+
keywords = keywords.dup
|
64
|
+
add_example(keywords.delete(:example)) if keywords.key?(:example)
|
65
|
+
|
66
|
+
@type = keywords.delete(:type)
|
67
|
+
@validations = {}
|
68
|
+
super(keywords)
|
69
|
+
end
|
70
|
+
|
71
|
+
def enum=(value) # :nodoc:
|
72
|
+
add_validation('enum', Validation::Enum.new(value))
|
73
|
+
@enum = value
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns true if and only if values can be +null+ as specified
|
77
|
+
# by \JSON \Schema.
|
78
|
+
def nullable?
|
79
|
+
existence <= Existence::ALLOW_NIL
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns a hash representing the \JSON \Schema object.
|
83
|
+
def to_json_schema
|
84
|
+
{
|
85
|
+
type: nullable? ? [type, 'null'] : type,
|
86
|
+
title: title,
|
87
|
+
description: description,
|
88
|
+
default: default,
|
89
|
+
examples: examples.presence,
|
90
|
+
deprecated: deprecated?.presence
|
91
|
+
}.tap do |hash|
|
92
|
+
validations.each_value do |validation|
|
93
|
+
hash.merge!(validation.to_json_schema_validation)
|
94
|
+
end
|
95
|
+
end.compact
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns a hash representing the \OpenAPI schema object.
|
99
|
+
def to_openapi(version)
|
100
|
+
version = OpenAPI::Version.from(version)
|
101
|
+
if version.major == 2
|
102
|
+
# OpenAPI 2.0
|
103
|
+
{
|
104
|
+
type: type,
|
105
|
+
example: examples&.first
|
106
|
+
}
|
107
|
+
elsif version.minor.zero?
|
108
|
+
# OpenAPI 3.0
|
109
|
+
{
|
110
|
+
type: type,
|
111
|
+
nullable: nullable?.presence,
|
112
|
+
examples: examples,
|
113
|
+
deprecated: deprecated?.presence
|
114
|
+
}
|
115
|
+
else
|
116
|
+
# OpenAPI 3.1
|
117
|
+
{
|
118
|
+
type: nullable? ? [type, 'null'] : type,
|
119
|
+
examples: examples,
|
120
|
+
deprecated: deprecated?.presence
|
121
|
+
}
|
122
|
+
end.tap do |hash|
|
123
|
+
hash[:title] = title
|
124
|
+
hash[:description] = description
|
125
|
+
hash[:default] = default
|
126
|
+
hash[:externalDocs] = external_docs&.to_openapi
|
127
|
+
|
128
|
+
validations.each_value do |validation|
|
129
|
+
hash.merge!(validation.to_openapi_validation(version))
|
130
|
+
end
|
131
|
+
end.compact
|
132
|
+
end
|
133
|
+
|
134
|
+
def type # :nodoc:
|
135
|
+
@type ||= self.class.name.demodulize.downcase
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
def add_validation(keyword, validation)
|
141
|
+
validations[keyword] = validation
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
module Schema
|
6
|
+
class Boundary
|
7
|
+
def self.from(value)
|
8
|
+
case value
|
9
|
+
when Boundary
|
10
|
+
value
|
11
|
+
when Hash
|
12
|
+
Boundary.new(value[:value], exclusive: value[:exclusive] == true)
|
13
|
+
else
|
14
|
+
Boundary.new(value)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# The value of the boundary.
|
19
|
+
attr_reader :value
|
20
|
+
|
21
|
+
def initialize(value, exclusive: false)
|
22
|
+
@value = value
|
23
|
+
@exclusive = exclusive
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns true if the boundary is exclusive, false otherwise.
|
27
|
+
def exclusive?
|
28
|
+
@exclusive == true
|
29
|
+
end
|
30
|
+
|
31
|
+
def inspect # :nodoc:
|
32
|
+
"#<#{self.class} value: #{value}, exclusive: #{exclusive?}>"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
|
5
|
+
module Jsapi
|
6
|
+
module Meta
|
7
|
+
module Schema
|
8
|
+
module Conversion
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
# The method or +Proc+ to convert objects by.
|
13
|
+
attr_accessor :conversion
|
14
|
+
end
|
15
|
+
|
16
|
+
def convert(object)
|
17
|
+
return object if conversion.nil?
|
18
|
+
|
19
|
+
if conversion.respond_to?(:call)
|
20
|
+
conversion.call(object)
|
21
|
+
else
|
22
|
+
object.send(conversion)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
module Schema
|
6
|
+
# Used by Reference to delegate method calls to the referred schema.
|
7
|
+
class Delegator
|
8
|
+
# The level of Existence.
|
9
|
+
attr_reader :existence
|
10
|
+
|
11
|
+
delegate_missing_to :@schema
|
12
|
+
|
13
|
+
def initialize(schema, existence)
|
14
|
+
@schema = schema
|
15
|
+
@existence = existence
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect # :nodoc:
|
19
|
+
"#<#{self.class.name} " \
|
20
|
+
"schema: #{@schema.inspect}, " \
|
21
|
+
"existence: #{@existence.inspect}>"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jsapi
|
4
|
+
module Meta
|
5
|
+
module Schema
|
6
|
+
class Discriminator < Meta::Base
|
7
|
+
##
|
8
|
+
# :attr: mappings
|
9
|
+
attribute :mappings, { String => String }
|
10
|
+
|
11
|
+
##
|
12
|
+
# :attr: property_name
|
13
|
+
attribute :property_name, String
|
14
|
+
|
15
|
+
# Looks up the inherriting schema for +value+ in +definitions+.
|
16
|
+
def resolve(value, definitions)
|
17
|
+
schema = definitions.schema(mapping(value) || value)
|
18
|
+
raise "inherriting schema not found: #{value.inspect}" unless schema
|
19
|
+
|
20
|
+
schema.resolve(definitions)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns a hash representing the \OpenAPI discriminator object.
|
24
|
+
def to_openapi(version)
|
25
|
+
version = OpenAPI::Version.from(version)
|
26
|
+
return property_name if version.major == 2
|
27
|
+
|
28
|
+
{
|
29
|
+
propertyName: property_name,
|
30
|
+
mapping: mappings
|
31
|
+
}.compact
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|