openapi3_parser 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 651f457272264ca4fc7b45040203a9fa7deeabde
|
4
|
+
data.tar.gz: b00561ee20a2c121d9f1d030511b07870cd66ecc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a38facc684d56b0194066ba88db7396107d882bc225fa07f14600bf21a5156c2f6032f8b284bac5146a6f3a9e792147e63fd35ca915b8b8d2f36fe57e738a662
|
7
|
+
data.tar.gz: f605fd5997afe6055b6e627eaca9971dd60dd6f2fbc19381a363490a596f46cf001317aed21130c4273115143c6353516c035747ab16867b62ece619434b6b1a
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -25,6 +25,19 @@ Documentation for the API to navigate the OpenAPI nodes is available on
|
|
25
25
|
[openapi-3]: https://github.com/OAI/OpenAPI-Specification
|
26
26
|
[docs]: http://www.rubydoc.info/github/kevindew/openapi3_parser/Openapi3Parser/Nodes/Openapi
|
27
27
|
|
28
|
+
## Installation
|
29
|
+
|
30
|
+
You can install this gem into your bundler application by adding this line to
|
31
|
+
your Gemfile:
|
32
|
+
|
33
|
+
```
|
34
|
+
gem "openapi3_parser", "~> 0.2.0"
|
35
|
+
```
|
36
|
+
|
37
|
+
and then running `$ bundle install`
|
38
|
+
|
39
|
+
Or install the gem onto your machine via ` $ gem install openapi3_parser`
|
40
|
+
|
28
41
|
## Status
|
29
42
|
|
30
43
|
This is currently a work in progress and will remain so until it reaches 1.0.
|
data/TODO.md
CHANGED
@@ -6,26 +6,29 @@ These are the steps defined to reach 1.0. Assistance is very welcome.
|
|
6
6
|
- [ ] Refactor the various NodeFactory modules to be a less confusing
|
7
7
|
hierachical structure. Consider having factories subclass instead of use
|
8
8
|
mixin
|
9
|
-
- [
|
9
|
+
- [x] Decouple Document class for the source file. Consider a source file class
|
10
10
|
instead
|
11
|
-
- [
|
11
|
+
- [x] Validate that a reference creates the type of node that is expected in
|
12
12
|
a context
|
13
|
-
- [
|
14
|
-
- [
|
15
|
-
- [
|
13
|
+
- [x] Allow opening of references from additional files
|
14
|
+
- [x] Allow opening of openapi documents by URL
|
15
|
+
- [x] Support references by URL
|
16
|
+
- [ ] Consider option to limit open by URL/path behaviour
|
16
17
|
- [ ] Support converting CommonMark to HTML
|
17
18
|
- [ ] Reach parity with OpenAPI specification for validation
|
18
19
|
- [ ] Consider a lenient mode for a document to only have to comply with type
|
19
20
|
based validation
|
20
21
|
- [ ] Improve test coverage
|
21
22
|
- [ ] Publish documentation of the interface through the structure
|
22
|
-
- [
|
23
|
+
- [x] Consider a resolved context class for representing context with a node
|
23
24
|
that can handle scenarios where a node is represented by both a reference
|
24
25
|
and resolved context
|
25
26
|
- [ ] Create error classes for various scenarios
|
26
27
|
- [ ] Associate/resolve operation id / operation references
|
27
28
|
- [ ] Do something to model expressions
|
28
|
-
- [
|
29
|
+
- [x] Improve the modelling of namespace
|
29
30
|
- [ ] Set up nicer string representations of key classes to help them be
|
30
31
|
debugged
|
31
|
-
- [
|
32
|
+
- [x] Ensure Array and Map nodes return empty ones by default rather than nil
|
33
|
+
- [ ] Make JSON pointer public access to be consistent accepting string, array
|
34
|
+
or (potentially) a pointer class
|
data/lib/openapi3_parser.rb
CHANGED
@@ -1,52 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "openapi3_parser/error"
|
4
3
|
require "openapi3_parser/document"
|
5
|
-
|
6
|
-
require "
|
7
|
-
require "
|
4
|
+
require "openapi3_parser/source_input/raw"
|
5
|
+
require "openapi3_parser/source_input/file"
|
6
|
+
require "openapi3_parser/source_input/url"
|
8
7
|
|
9
8
|
module Openapi3Parser
|
10
9
|
# For a variety of inputs this will construct an OpenAPI document. For a
|
11
10
|
# String/File input it will try to determine if the input is JSON or YAML.
|
12
11
|
#
|
13
|
-
# @param
|
12
|
+
# @param [String, Hash, File] input Source for the OpenAPI document
|
14
13
|
#
|
15
14
|
# @return [Document]
|
16
15
|
def self.load(input)
|
17
|
-
|
18
|
-
# File.dirname(input)
|
19
|
-
# else
|
20
|
-
# Dir.pwd
|
21
|
-
# end
|
22
|
-
|
23
|
-
Document.new(parse_input(input))
|
16
|
+
Document.new(SourceInput::Raw.new(input))
|
24
17
|
end
|
25
18
|
|
26
19
|
# For a given string filename this will read the file and parse it as an
|
27
20
|
# OpenAPI document. It will try detect automatically whether the contents
|
28
21
|
# are JSON or YAML.
|
29
22
|
#
|
30
|
-
# @param
|
23
|
+
# @param [String] path Filename of the OpenAPI document
|
31
24
|
#
|
32
25
|
# @return [Document]
|
33
26
|
def self.load_file(path)
|
34
|
-
|
35
|
-
load(file)
|
27
|
+
Document.new(SourceInput::File.new(path))
|
36
28
|
end
|
37
29
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
YAML.safe_load(contents, [], [], true)
|
48
|
-
end
|
30
|
+
# For a given string URL this will request the resource and parse it as an
|
31
|
+
# OpenAPI document. It will try detect automatically whether the contents
|
32
|
+
# are JSON or YAML.
|
33
|
+
#
|
34
|
+
# @param [String] url URL of the OpenAPI document
|
35
|
+
#
|
36
|
+
# @return [Document]
|
37
|
+
def self.load_url(url)
|
38
|
+
Document.new(SourceInput::Url.new(url.to_s))
|
49
39
|
end
|
50
|
-
|
51
|
-
private_class_method :parse_input
|
52
40
|
end
|
@@ -1,54 +1,112 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "openapi3_parser/context/location"
|
4
|
+
|
3
5
|
module Openapi3Parser
|
6
|
+
# Context is a construct used in both the node factories and the nodes
|
7
|
+
# themselves. It is used to represent the data, and the source of it, that
|
8
|
+
# a node is associated with. It also acts as a bridge between a node/node
|
9
|
+
# factory and associated document.
|
10
|
+
#
|
11
|
+
# @attr_reader input
|
12
|
+
# @attr_reader [Context::Location] document_location
|
13
|
+
# @attr_reader [Context::Location, nil] source_location
|
14
|
+
# @attr_reader [Context, nil] referenced_by
|
4
15
|
class Context
|
5
|
-
|
16
|
+
# Create a context for the root of a document
|
17
|
+
# @return [Context]
|
18
|
+
def self.root(input, source)
|
19
|
+
location = Location.new(source, [])
|
20
|
+
new(input, document_location: location)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Create a context for a field within the current contexts data
|
24
|
+
# eg for a context of:
|
25
|
+
# root = Context.root({ "test" => {} }, source)
|
26
|
+
# we can get the context of "test" with:
|
27
|
+
# test = Context.next_field(root, "test")
|
28
|
+
#
|
29
|
+
# @param [Context] parent_context
|
30
|
+
# @param [String] field
|
31
|
+
# @return [Context]
|
32
|
+
def self.next_field(parent_context, field)
|
33
|
+
pc = parent_context
|
34
|
+
input = pc.input.respond_to?(:[]) ? pc.input[field] : nil
|
35
|
+
new(input,
|
36
|
+
document_location: Location.next_field(pc.document_location, field),
|
37
|
+
source_location: Location.next_field(pc.source_location, field),
|
38
|
+
referenced_by: pc.referenced_by)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Creates the context for a field that is referenced by a context.
|
42
|
+
# In this scenario the context of the document is the same but we are in
|
43
|
+
# a different part of the source file, or even a different source file
|
44
|
+
#
|
45
|
+
# @param [Context] referencer_context
|
46
|
+
# @param input
|
47
|
+
# @param [Source] source
|
48
|
+
# @param [::Array] pointer_segments
|
49
|
+
# @return [Context]
|
50
|
+
def self.reference_field(referencer_context,
|
51
|
+
input:,
|
52
|
+
source:,
|
53
|
+
pointer_segments:)
|
54
|
+
new(input,
|
55
|
+
document_location: referencer_context.document_location,
|
56
|
+
source_location: Location.new(source, pointer_segments),
|
57
|
+
referenced_by: referencer_context)
|
58
|
+
end
|
59
|
+
|
60
|
+
attr_reader :input, :document_location, :source_location, :referenced_by
|
6
61
|
|
7
|
-
|
62
|
+
# @param input
|
63
|
+
# @param [Context::Location] document_location
|
64
|
+
# @param [Context::Location, nil] source_location
|
65
|
+
# @param [Context, nil] referenced_by
|
66
|
+
def initialize(input,
|
67
|
+
document_location:,
|
68
|
+
source_location: nil,
|
69
|
+
referenced_by: nil)
|
8
70
|
@input = input
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@
|
71
|
+
@document_location = document_location
|
72
|
+
@source_location = source_location || document_location
|
73
|
+
@referenced_by = referenced_by
|
12
74
|
end
|
13
75
|
|
14
|
-
|
15
|
-
|
76
|
+
# @return [Document]
|
77
|
+
def document
|
78
|
+
document_location.source.document
|
16
79
|
end
|
17
80
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
.map { |i| i.to_s.include?("/") ? %("#{i}") : i }
|
22
|
-
.join("/")
|
81
|
+
# @return [Source]
|
82
|
+
def source
|
83
|
+
source_location.source
|
23
84
|
end
|
24
85
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
input: next_input,
|
29
|
-
namespace: namespace + [segment],
|
30
|
-
document: document,
|
31
|
-
parent: self
|
32
|
-
)
|
86
|
+
# @return [Source::ReferenceResolver]
|
87
|
+
def register_reference(reference, factory)
|
88
|
+
source.register_reference(reference, factory, self)
|
33
89
|
end
|
34
90
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
next_context = resolved_reference(resolved_input, namespace)
|
39
|
-
yield(next_context)
|
40
|
-
end
|
91
|
+
# @deprecated
|
92
|
+
def namespace
|
93
|
+
document_location.pointer.segments
|
41
94
|
end
|
42
95
|
|
43
|
-
|
96
|
+
def inspect
|
97
|
+
%{#{self.class.name}(document_location: #{document_location}, } +
|
98
|
+
%{source_location: #{source_location}), referenced_by: } +
|
99
|
+
%{#{referenced_by})}
|
100
|
+
end
|
101
|
+
|
102
|
+
def location_summary
|
103
|
+
summary = document_location.to_s
|
104
|
+
summary += " (#{source_location})" if document_location != source_location
|
105
|
+
summary
|
106
|
+
end
|
44
107
|
|
45
|
-
def
|
46
|
-
|
47
|
-
input: input,
|
48
|
-
namespace: namespace,
|
49
|
-
document: document,
|
50
|
-
parent: parent
|
51
|
-
)
|
108
|
+
def to_s
|
109
|
+
location_summary
|
52
110
|
end
|
53
111
|
end
|
54
112
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "openapi3_parser/context/pointer"
|
4
|
+
|
5
|
+
module Openapi3Parser
|
6
|
+
class Context
|
7
|
+
# Class used to represent a location within an OpenAPI document.
|
8
|
+
# It contains a source, which is the source file/data used for the contents
|
9
|
+
# and the pointer which indicates where in the object like file the data is
|
10
|
+
class Location
|
11
|
+
def self.next_field(location, field)
|
12
|
+
new(location.source, location.pointer.segments + [field])
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :source, :pointer
|
16
|
+
|
17
|
+
# @param [Openapi3Parser::Source] source
|
18
|
+
# @param [::Array] pointer_segments
|
19
|
+
def initialize(source, pointer_segments)
|
20
|
+
@source = source
|
21
|
+
@pointer = Pointer.new(pointer_segments.freeze)
|
22
|
+
end
|
23
|
+
|
24
|
+
def ==(other)
|
25
|
+
source == other.source && pointer == other.pointer
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
source.relative_to_root + pointer.fragment
|
30
|
+
end
|
31
|
+
|
32
|
+
def inspect
|
33
|
+
%{#{self.class.name}(source: #{source.inspect}, pointer: #{pointer})}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Openapi3Parser
|
4
|
+
class Context
|
5
|
+
# A class to decorate the array of fields that make up a pointer and
|
6
|
+
# provide common means to convert it into different representations.
|
7
|
+
class Pointer
|
8
|
+
attr_reader :segments
|
9
|
+
|
10
|
+
# @param [::Array] segments
|
11
|
+
def initialize(segments)
|
12
|
+
@segments = segments.freeze
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
segments == other.segments
|
17
|
+
end
|
18
|
+
|
19
|
+
def fragment
|
20
|
+
segments.map { |s| CGI.escape(s.to_s).gsub("+", "%20") }
|
21
|
+
.join("/")
|
22
|
+
.prepend("#/")
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
fragment
|
27
|
+
end
|
28
|
+
|
29
|
+
def inspect
|
30
|
+
%{#{self.class.name}(segments: #{segments}, fragment: "#{fragment}")}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,48 +1,148 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "openapi3_parser/context"
|
4
|
+
require "openapi3_parser/document/reference_register"
|
4
5
|
require "openapi3_parser/error"
|
5
6
|
require "openapi3_parser/node_factories/openapi"
|
7
|
+
require "openapi3_parser/source"
|
8
|
+
require "openapi3_parser/validation/error_collection"
|
6
9
|
|
7
10
|
require "forwardable"
|
8
11
|
|
9
12
|
module Openapi3Parser
|
13
|
+
# Document is the root construct of a created OpenAPI Document and can be
|
14
|
+
# used to navigate the contents of a document or to check it's validity.
|
15
|
+
#
|
16
|
+
# @attr_reader [Source] root_source
|
10
17
|
class Document
|
11
18
|
extend Forwardable
|
19
|
+
include Enumerable
|
12
20
|
|
13
|
-
attr_reader :
|
21
|
+
attr_reader :root_source
|
14
22
|
|
15
|
-
|
23
|
+
# @!method valid?
|
24
|
+
# Whether this OpenAPI document has any validation issues or not. See
|
25
|
+
# #errors to access the errors
|
26
|
+
#
|
27
|
+
# @return [Boolean]
|
28
|
+
def_delegator :factory, :valid?
|
29
|
+
|
30
|
+
# @!method openapi
|
31
|
+
# The value of the openapi version field for this document
|
32
|
+
# @see Nodes::Openapi#openapi
|
33
|
+
# @return [String]
|
34
|
+
# @!method info
|
35
|
+
# The value of the info field on the OpenAPI document
|
36
|
+
# @see Nodes::Openapi#info
|
37
|
+
# @return [Nodes::Info]
|
38
|
+
# @!method servers
|
39
|
+
# The value of the servers field on the OpenAPI document
|
40
|
+
# @see Nodes::Openapi#servers
|
41
|
+
# @return [Nodes::Array<Nodes::Server>]
|
42
|
+
# @!method paths
|
43
|
+
# The value of the paths field on the OpenAPI document
|
44
|
+
# @see Nodes::Openapi#paths
|
45
|
+
# @return [Nodes::Paths]
|
46
|
+
# @!method components
|
47
|
+
# The value of the components field on the OpenAPI document
|
48
|
+
# @see Nodes::Openapi#components
|
49
|
+
# @return [Nodes::Components]
|
50
|
+
# @!method security
|
51
|
+
# The value of the security field on the OpenAPI document
|
52
|
+
# @see Nodes::Openapi#security
|
53
|
+
# @return [Nodes::Array<Nodes::SecurityRequirement>]
|
54
|
+
# @!method tags
|
55
|
+
# The value of the tags field on the OpenAPI document
|
56
|
+
# @see Nodes::Openapi#tags
|
57
|
+
# @return [Nodes::Array<Nodes::Tag>]
|
58
|
+
# @!method external_docs
|
59
|
+
# The value of the external_docs field on the OpenAPI document
|
60
|
+
# @see Nodes::Openapi#external_docs
|
61
|
+
# @return [Nodes::ExternalDocumentation]
|
62
|
+
# @!method extension
|
63
|
+
# Look up an extension field provided for the root object of the document
|
64
|
+
# @see Node::Object#extension
|
65
|
+
# @return [Hash, Array, Numeric, String, true, false, nil]
|
66
|
+
# @!method []
|
67
|
+
# Look up an attribute on the root of the OpenAPI document by String
|
68
|
+
# or Symbol
|
69
|
+
# @see Node::Object#[]
|
70
|
+
# @return Object
|
71
|
+
# @!method each
|
72
|
+
# Iterate through the attributes of the root object
|
73
|
+
# @see Node::Object#each
|
16
74
|
def_delegators :root, :openapi, :info, :servers, :paths, :components,
|
17
75
|
:security, :tags, :external_docs, :extension, :[], :each
|
18
76
|
|
19
|
-
|
20
|
-
|
77
|
+
# @param [SourceInput] source_input
|
78
|
+
def initialize(source_input)
|
79
|
+
@reference_register = ReferenceRegister.new
|
80
|
+
@root_source = Source.new(source_input, self, reference_register)
|
81
|
+
@build_in_progress = false
|
82
|
+
@built = false
|
21
83
|
end
|
22
84
|
|
85
|
+
# @return [Nodes::Openapi]
|
23
86
|
def root
|
24
87
|
factory.node
|
25
88
|
end
|
26
89
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
90
|
+
# All the additional sources that have been referenced as part of loading
|
91
|
+
# the OpenAPI document
|
92
|
+
#
|
93
|
+
# @return [Array<Source>]
|
94
|
+
def reference_sources
|
95
|
+
build unless built
|
96
|
+
reference_register.sources
|
97
|
+
end
|
31
98
|
|
32
|
-
|
33
|
-
|
34
|
-
|
99
|
+
# All of the sources involved in this OpenAPI document
|
100
|
+
#
|
101
|
+
# @return [Array<Source>]
|
102
|
+
def sources
|
103
|
+
[root_source] + reference_sources
|
104
|
+
end
|
35
105
|
|
36
|
-
|
37
|
-
|
106
|
+
# Any validation errors that are present on the OpenAPI document
|
107
|
+
#
|
108
|
+
# @return [Validation::ErrorCollection]
|
109
|
+
def errors
|
110
|
+
reference_factories.inject(factory.errors) do |memo, f|
|
111
|
+
Validation::ErrorCollection.combine(memo, f.errors)
|
112
|
+
end
|
113
|
+
end
|
38
114
|
|
39
|
-
|
115
|
+
# Look up whether an instance of SourceInput is already a known source
|
116
|
+
# for this document.
|
117
|
+
#
|
118
|
+
# @param [SourceInput] source_input
|
119
|
+
# @return [Source, nil]
|
120
|
+
def source_for_source_input(source_input)
|
121
|
+
sources.find { |source| source.source_input == source_input }
|
40
122
|
end
|
41
123
|
|
42
124
|
private
|
43
125
|
|
126
|
+
attr_reader :reference_register, :built, :build_in_progress
|
127
|
+
|
128
|
+
def build
|
129
|
+
return if build_in_progress || built
|
130
|
+
@build_in_progress = true
|
131
|
+
context = Context.root(root_source.data, root_source)
|
132
|
+
@factory = NodeFactories::Openapi.new(context)
|
133
|
+
reference_register.freeze
|
134
|
+
@build_in_progress = false
|
135
|
+
@built = true
|
136
|
+
end
|
137
|
+
|
44
138
|
def factory
|
45
|
-
|
139
|
+
build unless built
|
140
|
+
@factory
|
141
|
+
end
|
142
|
+
|
143
|
+
def reference_factories
|
144
|
+
build unless built
|
145
|
+
reference_register.factories
|
46
146
|
end
|
47
147
|
end
|
48
148
|
end
|