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
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
|