openapi3_parser 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/.travis.yml +10 -1
- data/CHANGELOG.md +5 -0
- data/README.md +13 -0
- data/TODO.md +11 -8
- data/lib/openapi3_parser.rb +16 -28
- data/lib/openapi3_parser/context.rb +92 -34
- data/lib/openapi3_parser/context/location.rb +37 -0
- data/lib/openapi3_parser/context/pointer.rb +34 -0
- data/lib/openapi3_parser/document.rb +115 -15
- data/lib/openapi3_parser/document/reference_register.rb +50 -0
- data/lib/openapi3_parser/error.rb +27 -1
- data/lib/openapi3_parser/node/object.rb +26 -1
- data/lib/openapi3_parser/node_factories/array.rb +15 -14
- data/lib/openapi3_parser/node_factories/callback.rb +2 -1
- data/lib/openapi3_parser/node_factories/link.rb +1 -1
- data/lib/openapi3_parser/node_factories/map.rb +13 -11
- data/lib/openapi3_parser/node_factories/openapi.rb +2 -0
- data/lib/openapi3_parser/node_factories/path_item.rb +13 -18
- data/lib/openapi3_parser/node_factories/paths.rb +2 -1
- data/lib/openapi3_parser/node_factories/reference.rb +7 -9
- data/lib/openapi3_parser/node_factories/responses.rb +4 -2
- data/lib/openapi3_parser/node_factories/security_requirement.rb +2 -1
- data/lib/openapi3_parser/node_factory.rb +39 -30
- data/lib/openapi3_parser/node_factory/fields/reference.rb +44 -0
- data/lib/openapi3_parser/node_factory/map.rb +5 -5
- data/lib/openapi3_parser/node_factory/object.rb +6 -5
- data/lib/openapi3_parser/node_factory/object/node_builder.rb +12 -11
- data/lib/openapi3_parser/node_factory/object/validator.rb +25 -14
- data/lib/openapi3_parser/nodes/components.rb +9 -11
- data/lib/openapi3_parser/nodes/discriminator.rb +1 -1
- data/lib/openapi3_parser/nodes/encoding.rb +1 -1
- data/lib/openapi3_parser/nodes/link.rb +1 -1
- data/lib/openapi3_parser/nodes/media_type.rb +2 -2
- data/lib/openapi3_parser/nodes/oauth_flow.rb +1 -1
- data/lib/openapi3_parser/nodes/openapi.rb +3 -4
- data/lib/openapi3_parser/nodes/operation.rb +5 -8
- data/lib/openapi3_parser/nodes/parameter/parameter_like.rb +2 -2
- data/lib/openapi3_parser/nodes/path_item.rb +2 -3
- data/lib/openapi3_parser/nodes/request_body.rb +1 -1
- data/lib/openapi3_parser/nodes/response.rb +3 -3
- data/lib/openapi3_parser/nodes/schema.rb +6 -7
- data/lib/openapi3_parser/nodes/server.rb +1 -2
- data/lib/openapi3_parser/nodes/server_variable.rb +1 -1
- data/lib/openapi3_parser/source.rb +136 -0
- data/lib/openapi3_parser/source/reference.rb +68 -0
- data/lib/openapi3_parser/source/reference_resolver.rb +81 -0
- data/lib/openapi3_parser/source_input.rb +71 -0
- data/lib/openapi3_parser/source_input/file.rb +102 -0
- data/lib/openapi3_parser/source_input/raw.rb +90 -0
- data/lib/openapi3_parser/source_input/resolve_next.rb +62 -0
- data/lib/openapi3_parser/source_input/string_parser.rb +43 -0
- data/lib/openapi3_parser/source_input/url.rb +123 -0
- data/lib/openapi3_parser/validation/error.rb +36 -3
- data/lib/openapi3_parser/validation/error_collection.rb +57 -15
- data/lib/openapi3_parser/validators/reference.rb +40 -0
- data/lib/openapi3_parser/version.rb +1 -1
- data/openapi3_parser.gemspec +10 -5
- metadata +34 -20
- data/lib/openapi3_parser/fields/map.rb +0 -83
- data/lib/openapi3_parser/node.rb +0 -115
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "openapi3_parser/error"
|
4
|
+
|
5
|
+
module Openapi3Parser
|
6
|
+
class Document
|
7
|
+
class ReferenceRegister
|
8
|
+
attr_reader :sources, :factories
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@sources = []
|
12
|
+
@factories = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def register(factory)
|
16
|
+
error = "Can't register references when the register is frozen"
|
17
|
+
raise Error::ImmutableObject, error if frozen?
|
18
|
+
context = factory.context
|
19
|
+
add_source(context.source_location.source)
|
20
|
+
add_factory(factory)
|
21
|
+
end
|
22
|
+
|
23
|
+
def freeze
|
24
|
+
sources.freeze
|
25
|
+
factories.freeze
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def add_source(source)
|
32
|
+
return if sources.include?(source)
|
33
|
+
sources << source
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_factory(factory)
|
37
|
+
return if factory_registered?(factory)
|
38
|
+
factories << factory
|
39
|
+
end
|
40
|
+
|
41
|
+
def factory_registered?(factory)
|
42
|
+
source_location = factory.context.source_location
|
43
|
+
factories.any? do |f|
|
44
|
+
same_location = f.context.source_location == source_location
|
45
|
+
same_location && f.class == factory.class
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,5 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Openapi3Parser
|
4
|
-
class
|
4
|
+
# An abstract class for Exceptions produced by this Gem
|
5
|
+
class Error < ::RuntimeError
|
6
|
+
# Raised in cases where we have been provided a path or URL to a file and
|
7
|
+
# at runtime when we have tried to access that resource it is not available
|
8
|
+
# for whatever reason.
|
9
|
+
class InaccessibleInput < Error; end
|
10
|
+
# Raised in cases where we provided data that we expected to be parsable
|
11
|
+
# (such as a string of JSON data) but when we tried to parse it an error
|
12
|
+
# is raised
|
13
|
+
class UnparsableInput < Error; end
|
14
|
+
# Raised in cases where an object that is in an immutable state is modified
|
15
|
+
#
|
16
|
+
# Typically this would occur when a component that is frozen is modififed.
|
17
|
+
# Some components are mutable during the construction of a document and
|
18
|
+
# then frozen afterwards.
|
19
|
+
class ImmutableObject < Error; end
|
20
|
+
# Raised when a type that is not a whitelist of valid types is used
|
21
|
+
class InvalidType < Error; end
|
22
|
+
# Raised when we have to abort creating an object due to invalid data
|
23
|
+
class InvalidData < Error; end
|
24
|
+
# Used when there are fields that are missing from an object which prevents
|
25
|
+
# us from creating a node
|
26
|
+
class MissingFields < Error; end
|
27
|
+
# Used when there are extra fields that are not expected in the data for
|
28
|
+
# a node
|
29
|
+
class UnexpectedFields < Error; end
|
30
|
+
end
|
5
31
|
end
|
@@ -12,14 +12,39 @@ module Openapi3Parser
|
|
12
12
|
@node_context = context
|
13
13
|
end
|
14
14
|
|
15
|
+
# Look up an attribute of the node by the name it has in the OpenAPI
|
16
|
+
# document.
|
17
|
+
#
|
18
|
+
# @example Look up by OpenAPI naming
|
19
|
+
# obj["externalDocs"]
|
20
|
+
#
|
21
|
+
# @example Look up by symbol
|
22
|
+
# obj[:servers]
|
23
|
+
#
|
24
|
+
# @example Look up an extension
|
25
|
+
# obj["x-myExtension"]
|
26
|
+
#
|
27
|
+
# @param [String, Symbol] value
|
28
|
+
#
|
29
|
+
# @return anything
|
15
30
|
def [](value)
|
16
|
-
node_data[value]
|
31
|
+
node_data[value.to_s]
|
17
32
|
end
|
18
33
|
|
34
|
+
# Look up an extension provided for this object, doesn't need a prefix of
|
35
|
+
# "x-"
|
36
|
+
#
|
37
|
+
# @example Looking up an extension provided as "x-extra"
|
38
|
+
# obj.extension("extra")
|
39
|
+
#
|
40
|
+
# @param [String, Symbol] value
|
41
|
+
#
|
42
|
+
# @return [Hash, Array, Numeric, String, true, false, nil]
|
19
43
|
def extension(value)
|
20
44
|
node_data["x-#{value}"]
|
21
45
|
end
|
22
46
|
|
47
|
+
# Iterate through the attributes of this object
|
23
48
|
def each(&block)
|
24
49
|
node_data.each(&block)
|
25
50
|
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "openapi3_parser/context"
|
4
|
+
require "openapi3_parser/error"
|
3
5
|
require "openapi3_parser/node_factory"
|
4
6
|
require "openapi3_parser/nodes/array"
|
5
7
|
require "openapi3_parser/validation/error"
|
8
|
+
require "openapi3_parser/validation/error_collection"
|
6
9
|
|
7
10
|
module Openapi3Parser
|
8
11
|
module NodeFactories
|
@@ -17,11 +20,11 @@ module Openapi3Parser
|
|
17
20
|
value_factory: nil,
|
18
21
|
validate: nil
|
19
22
|
)
|
20
|
-
super(context)
|
21
23
|
@default = default
|
22
24
|
@given_value_input_type = value_input_type
|
23
25
|
@given_value_factory = value_factory
|
24
26
|
@given_validate = validate
|
27
|
+
super(context)
|
25
28
|
end
|
26
29
|
|
27
30
|
private
|
@@ -32,7 +35,7 @@ module Openapi3Parser
|
|
32
35
|
def process_input(input)
|
33
36
|
input.each_with_index.map do |value, i|
|
34
37
|
if value_factory?
|
35
|
-
initialize_value_factory(
|
38
|
+
initialize_value_factory(Context.next_field(context, i))
|
36
39
|
else
|
37
40
|
value
|
38
41
|
end
|
@@ -43,15 +46,13 @@ module Openapi3Parser
|
|
43
46
|
given_validate&.call(input, context)
|
44
47
|
end
|
45
48
|
|
46
|
-
def validate_input
|
47
|
-
|
48
|
-
|
49
|
-
next unless value.respond_to?(:errors)
|
50
|
-
error_collection.merge(value.errors)
|
49
|
+
def validate_input
|
50
|
+
value_errors = processed_input.flat_map do |value|
|
51
|
+
value.respond_to?(:errors) ? value.errors.to_a : []
|
51
52
|
end
|
52
|
-
|
53
|
-
|
54
|
-
)
|
53
|
+
errors = value_errors + validate_value_input_type(processed_input,
|
54
|
+
context)
|
55
|
+
Validation::ErrorCollection.combine(super, errors)
|
55
56
|
end
|
56
57
|
|
57
58
|
def build_node(input)
|
@@ -81,7 +82,7 @@ module Openapi3Parser
|
|
81
82
|
error = error_for_value_input_type(value)
|
82
83
|
next unless error
|
83
84
|
memo << Validation::Error.new(
|
84
|
-
|
85
|
+
error, Context.next_field(context, i), self.class
|
85
86
|
)
|
86
87
|
end
|
87
88
|
end
|
@@ -90,9 +91,9 @@ module Openapi3Parser
|
|
90
91
|
input.each_with_index do |value, i|
|
91
92
|
error = error_for_value_input_type(value)
|
92
93
|
next unless error
|
93
|
-
next_context =
|
94
|
-
raise Openapi3Parser::Error,
|
95
|
-
"Invalid type for #{next_context.
|
94
|
+
next_context = Context.next_field(context, i)
|
95
|
+
raise Openapi3Parser::Error::InvalidType,
|
96
|
+
"Invalid type for #{next_context.location_summary}. "\
|
96
97
|
"#{error}"
|
97
98
|
end
|
98
99
|
end
|
@@ -14,7 +14,8 @@ module Openapi3Parser
|
|
14
14
|
def process_input(input)
|
15
15
|
input.each_with_object({}) do |(key, value), memo|
|
16
16
|
memo[key] = value if extension?(key)
|
17
|
-
|
17
|
+
next_context = Context.next_field(context, key)
|
18
|
+
memo[key] = NodeFactories::PathItem.new(next_context)
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
@@ -12,7 +12,7 @@ module Openapi3Parser
|
|
12
12
|
|
13
13
|
allow_extensions
|
14
14
|
|
15
|
-
# @
|
15
|
+
# @todo The link object in OAS is pretty meaty and there's lot of scope
|
16
16
|
# for further work here to make use of it's funcationality
|
17
17
|
|
18
18
|
field "operationRef", input_type: String
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "openapi3_parser/context"
|
4
|
+
require "openapi3_parser/error"
|
3
5
|
require "openapi3_parser/node_factory/map"
|
4
6
|
require "openapi3_parser/nodes/map"
|
5
7
|
require "openapi3_parser/validation/error"
|
8
|
+
require "openapi3_parser/validation/error_collection"
|
6
9
|
|
7
10
|
module Openapi3Parser
|
8
11
|
module NodeFactories
|
@@ -16,11 +19,11 @@ module Openapi3Parser
|
|
16
19
|
value_factory: nil,
|
17
20
|
validate: nil
|
18
21
|
)
|
19
|
-
super(context)
|
20
22
|
@given_key_input_type = key_input_type
|
21
23
|
@given_value_input_type = value_input_type
|
22
24
|
@given_value_factory = value_factory
|
23
25
|
@given_validate = validate
|
26
|
+
super(context)
|
24
27
|
end
|
25
28
|
|
26
29
|
private
|
@@ -31,7 +34,8 @@ module Openapi3Parser
|
|
31
34
|
def process_input(input)
|
32
35
|
input.each_with_object({}) do |(key, value), memo|
|
33
36
|
memo[key] = if value_factory?
|
34
|
-
|
37
|
+
next_context = Context.next_field(context, key)
|
38
|
+
initialize_value_factory(next_context)
|
35
39
|
else
|
36
40
|
value
|
37
41
|
end
|
@@ -53,11 +57,9 @@ module Openapi3Parser
|
|
53
57
|
given_validate&.call(input, context)
|
54
58
|
end
|
55
59
|
|
56
|
-
def validate_input
|
57
|
-
|
58
|
-
|
59
|
-
validate_value_input_type(processed_input, context)
|
60
|
-
)
|
60
|
+
def validate_input
|
61
|
+
errors = validate_value_input_type(processed_input, context)
|
62
|
+
Validation::ErrorCollection.combine(super, errors)
|
61
63
|
end
|
62
64
|
|
63
65
|
def build_node(input)
|
@@ -84,7 +86,7 @@ module Openapi3Parser
|
|
84
86
|
error = error_for_value_input_type(value)
|
85
87
|
next unless error
|
86
88
|
memo << Validation::Error.new(
|
87
|
-
|
89
|
+
error, Context.next_field(context, key), self.class
|
88
90
|
)
|
89
91
|
end
|
90
92
|
end
|
@@ -93,9 +95,9 @@ module Openapi3Parser
|
|
93
95
|
input.each do |key, value|
|
94
96
|
error = error_for_value_input_type(value)
|
95
97
|
next unless error
|
96
|
-
next_context =
|
97
|
-
raise Openapi3Parser::Error,
|
98
|
-
"Invalid type for #{next_context.
|
98
|
+
next_context = Context.next_field(context, key)
|
99
|
+
raise Openapi3Parser::Error::InvalidType,
|
100
|
+
"Invalid type for #{next_context.location_summary}. "\
|
99
101
|
"#{error}"
|
100
102
|
end
|
101
103
|
end
|
@@ -17,6 +17,8 @@ module Openapi3Parser
|
|
17
17
|
include NodeFactory::Object
|
18
18
|
|
19
19
|
allow_extensions
|
20
|
+
disallow_default
|
21
|
+
|
20
22
|
field "openapi", input_type: String, required: true
|
21
23
|
field "info", factory: NodeFactories::Info, required: true
|
22
24
|
field "servers", factory: :servers_factory
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "openapi3_parser/nodes/path_item"
|
4
|
+
require "openapi3_parser/node_factory/fields/reference"
|
4
5
|
require "openapi3_parser/node_factory/object"
|
5
6
|
require "openapi3_parser/node_factory/object/node_builder"
|
6
7
|
require "openapi3_parser/node_factory/optional_reference"
|
@@ -15,7 +16,7 @@ module Openapi3Parser
|
|
15
16
|
include NodeFactory::Object
|
16
17
|
|
17
18
|
allow_extensions
|
18
|
-
field "$ref", input_type: String
|
19
|
+
field "$ref", input_type: String, factory: :ref_factory
|
19
20
|
field "summary", input_type: String
|
20
21
|
field "description", input_type: String
|
21
22
|
field "get", factory: :operation_factory
|
@@ -36,9 +37,17 @@ module Openapi3Parser
|
|
36
37
|
private
|
37
38
|
|
38
39
|
def build_object(data, context)
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
ref = data.delete("$ref")
|
41
|
+
return Nodes::PathItem.new(data, context) unless ref
|
42
|
+
|
43
|
+
merged_data = ref.node_data.merge(data) do |_, new, old|
|
44
|
+
new.nil? ? old : new
|
45
|
+
end
|
46
|
+
Nodes::PathItem.new(merged_data, ref.node_context)
|
47
|
+
end
|
48
|
+
|
49
|
+
def ref_factory(context)
|
50
|
+
Fields::Reference.new(context, self.class)
|
42
51
|
end
|
43
52
|
|
44
53
|
def operation_factory(context)
|
@@ -56,20 +65,6 @@ module Openapi3Parser
|
|
56
65
|
factory = NodeFactory::OptionalReference.new(NodeFactories::Parameter)
|
57
66
|
NodeFactories::Array.new(context, value_factory: factory)
|
58
67
|
end
|
59
|
-
|
60
|
-
def merge_reference(data, context)
|
61
|
-
return data unless data["$ref"]
|
62
|
-
factory = context.resolve_reference do |ref_context|
|
63
|
-
self.class.new(ref_context)
|
64
|
-
end
|
65
|
-
|
66
|
-
# @TODO In this situation we're basically sacrificing the reference
|
67
|
-
# context as we don't know how to merge them. Should develop a system
|
68
|
-
# to have a dual context
|
69
|
-
factory.node_data.merge(data) do |_, new, old|
|
70
|
-
new.nil? ? old : new
|
71
|
-
end
|
72
|
-
end
|
73
68
|
end
|
74
69
|
end
|
75
70
|
end
|
@@ -15,7 +15,8 @@ module Openapi3Parser
|
|
15
15
|
def process_input(input)
|
16
16
|
input.each_with_object({}) do |(key, value), memo|
|
17
17
|
memo[key] = value if extension?(key)
|
18
|
-
|
18
|
+
next_context = Context.next_field(context, key)
|
19
|
+
memo[key] = child_factory(next_context)
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
@@ -1,32 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "openapi3_parser/node_factory/object"
|
4
|
+
require "openapi3_parser/node_factory/fields/reference"
|
4
5
|
|
5
6
|
module Openapi3Parser
|
6
7
|
module NodeFactories
|
7
8
|
class Reference
|
8
9
|
include NodeFactory::Object
|
9
10
|
|
10
|
-
field "$ref", input_type: String, required: true
|
11
|
+
field "$ref", input_type: String, required: true, factory: :ref_factory
|
11
12
|
|
12
13
|
attr_reader :factory
|
13
14
|
|
14
15
|
def initialize(context, factory)
|
15
|
-
super(context)
|
16
16
|
@factory = factory
|
17
|
+
super(context)
|
17
18
|
end
|
18
19
|
|
19
20
|
private
|
20
21
|
|
21
|
-
def
|
22
|
-
|
23
|
-
resolve_factory(ref_context).node
|
24
|
-
end
|
22
|
+
def build_node(input)
|
23
|
+
input["$ref"].node
|
25
24
|
end
|
26
25
|
|
27
|
-
def
|
28
|
-
|
29
|
-
factory.call(ref_context)
|
26
|
+
def ref_factory(context)
|
27
|
+
Fields::Reference.new(context, factory)
|
30
28
|
end
|
31
29
|
end
|
32
30
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "openapi3_parser/context"
|
4
|
+
require "openapi3_parser/node_factories/response"
|
3
5
|
require "openapi3_parser/node_factory/map"
|
4
6
|
require "openapi3_parser/node_factory/optional_reference"
|
5
7
|
require "openapi3_parser/nodes/responses"
|
6
|
-
require "openapi3_parser/node_factories/response"
|
7
8
|
|
8
9
|
module Openapi3Parser
|
9
10
|
module NodeFactories
|
@@ -15,7 +16,8 @@ module Openapi3Parser
|
|
15
16
|
def process_input(input)
|
16
17
|
input.each_with_object({}) do |(key, value), memo|
|
17
18
|
memo[key] = value if extension?(key)
|
18
|
-
|
19
|
+
next_context = Context.next_field(context, key)
|
20
|
+
memo[key] = child_factory(next_context)
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
@@ -13,7 +13,8 @@ module Openapi3Parser
|
|
13
13
|
|
14
14
|
def process_input(input)
|
15
15
|
input.keys.each_with_object({}) do |key, memo|
|
16
|
-
|
16
|
+
next_context = Context.next_field(context, key)
|
17
|
+
memo[key] = NodeFactories::Array.new(next_context)
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "openapi3_parser/context"
|
3
4
|
require "openapi3_parser/error"
|
4
5
|
require "openapi3_parser/validation/error"
|
5
6
|
require "openapi3_parser/validation/error_collection"
|
@@ -19,18 +20,36 @@ module Openapi3Parser
|
|
19
20
|
def expected_input_type
|
20
21
|
@input_type
|
21
22
|
end
|
23
|
+
|
24
|
+
def allow_default
|
25
|
+
@allow_default = true
|
26
|
+
end
|
27
|
+
|
28
|
+
def disallow_default
|
29
|
+
@allow_default = false
|
30
|
+
end
|
31
|
+
|
32
|
+
def allowed_default?
|
33
|
+
@allow_default.nil? || @allow_default
|
34
|
+
end
|
22
35
|
end
|
23
36
|
|
24
37
|
def self.included(base)
|
25
38
|
base.extend(ClassMethods)
|
26
39
|
end
|
27
40
|
|
41
|
+
def allowed_default?
|
42
|
+
self.class.allowed_default?
|
43
|
+
end
|
44
|
+
|
28
45
|
EXTENSION_REGEX = /^x-(.*)/
|
29
46
|
|
30
47
|
attr_reader :context
|
31
48
|
|
32
49
|
def initialize(context)
|
33
50
|
@context = context
|
51
|
+
input = nil_input? ? default : context.input
|
52
|
+
@processed_input = input.nil? ? nil : process_input(input)
|
34
53
|
end
|
35
54
|
|
36
55
|
def valid?
|
@@ -51,47 +70,44 @@ module Openapi3Parser
|
|
51
70
|
|
52
71
|
private
|
53
72
|
|
73
|
+
attr_reader :processed_input
|
74
|
+
|
54
75
|
def validate(_input, _context); end
|
55
76
|
|
56
|
-
def validate_input
|
57
|
-
|
58
|
-
validate(context.input, context),
|
59
|
-
error_collection
|
60
|
-
)
|
77
|
+
def validate_input
|
78
|
+
transform_errors(validate(context.input, context))
|
61
79
|
end
|
62
80
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
81
|
+
def transform_errors(errors)
|
82
|
+
error_objects = Array(errors).map do |error|
|
83
|
+
if !error.is_a?(Validation::Error)
|
84
|
+
error
|
85
|
+
else
|
86
|
+
Validation::Error.new(error, context, self.class)
|
68
87
|
end
|
69
|
-
error_collection.append(error)
|
70
88
|
end
|
71
|
-
|
89
|
+
Validation::ErrorCollection.new(error_objects)
|
72
90
|
end
|
73
91
|
|
74
92
|
def build_errors
|
75
|
-
|
76
|
-
return error_collection if nil_input?
|
93
|
+
return Validation::ErrorCollection.new if nil_input? && allowed_default?
|
77
94
|
unless valid_type?
|
78
95
|
error = Validation::Error.new(
|
79
|
-
|
96
|
+
"Invalid type. #{validate_type}", context, self.class
|
80
97
|
)
|
81
|
-
return
|
98
|
+
return Validation::ErrorCollection.new([error])
|
82
99
|
end
|
83
|
-
validate_input
|
84
|
-
error_collection
|
100
|
+
validate_input
|
85
101
|
end
|
86
102
|
|
87
103
|
def build_valid_node
|
88
|
-
if nil_input?
|
104
|
+
if nil_input? && allowed_default?
|
89
105
|
return default.nil? ? nil : build_node(processed_input)
|
90
106
|
end
|
91
107
|
|
92
108
|
unless valid_type?
|
93
|
-
raise Openapi3Parser::Error,
|
94
|
-
"Invalid type for #{context.
|
109
|
+
raise Openapi3Parser::Error::InvalidType,
|
110
|
+
"Invalid type for #{context.location_summary}. "\
|
95
111
|
"#{validate_type}"
|
96
112
|
end
|
97
113
|
|
@@ -102,8 +118,8 @@ module Openapi3Parser
|
|
102
118
|
def validate_before_build
|
103
119
|
errors = Array(validate(context.input, context))
|
104
120
|
return unless errors.any?
|
105
|
-
raise Openapi3Parser::Error,
|
106
|
-
"Invalid data for #{context.
|
121
|
+
raise Openapi3Parser::Error::InvalidData,
|
122
|
+
"Invalid data for #{context.location_summary}. "\
|
107
123
|
"#{errors.join(', ')}"
|
108
124
|
end
|
109
125
|
|
@@ -116,13 +132,6 @@ module Openapi3Parser
|
|
116
132
|
return "Expected #{self.class.expected_input_type}" unless valid_type
|
117
133
|
end
|
118
134
|
|
119
|
-
def processed_input
|
120
|
-
@processed_input ||= begin
|
121
|
-
input = nil_input? ? default : context.input
|
122
|
-
process_input(input)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
135
|
def process_input(input)
|
127
136
|
input
|
128
137
|
end
|