openapi3_parser 0.1.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 +7 -0
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.rubocop.yml +9 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +5 -0
- data/LICENCE +19 -0
- data/README.md +32 -0
- data/Rakefile +10 -0
- data/TODO.md +30 -0
- data/lib/openapi3_parser.rb +39 -0
- data/lib/openapi3_parser/context.rb +54 -0
- data/lib/openapi3_parser/document.rb +48 -0
- data/lib/openapi3_parser/error.rb +5 -0
- data/lib/openapi3_parser/fields/map.rb +83 -0
- data/lib/openapi3_parser/node.rb +115 -0
- data/lib/openapi3_parser/node/map.rb +24 -0
- data/lib/openapi3_parser/node/object.rb +28 -0
- data/lib/openapi3_parser/node_factories/array.rb +105 -0
- data/lib/openapi3_parser/node_factories/callback.rb +26 -0
- data/lib/openapi3_parser/node_factories/components.rb +83 -0
- data/lib/openapi3_parser/node_factories/contact.rb +24 -0
- data/lib/openapi3_parser/node_factories/discriminator.rb +31 -0
- data/lib/openapi3_parser/node_factories/encoding.rb +34 -0
- data/lib/openapi3_parser/node_factories/example.rb +25 -0
- data/lib/openapi3_parser/node_factories/external_documentation.rb +23 -0
- data/lib/openapi3_parser/node_factories/header.rb +36 -0
- data/lib/openapi3_parser/node_factories/info.rb +28 -0
- data/lib/openapi3_parser/node_factories/license.rb +22 -0
- data/lib/openapi3_parser/node_factories/link.rb +40 -0
- data/lib/openapi3_parser/node_factories/map.rb +110 -0
- data/lib/openapi3_parser/node_factories/media_type.rb +44 -0
- data/lib/openapi3_parser/node_factories/oauth_flow.rb +24 -0
- data/lib/openapi3_parser/node_factories/oauth_flows.rb +31 -0
- data/lib/openapi3_parser/node_factories/openapi.rb +50 -0
- data/lib/openapi3_parser/node_factories/operation.rb +76 -0
- data/lib/openapi3_parser/node_factories/parameter.rb +43 -0
- data/lib/openapi3_parser/node_factories/parameter/parameter_like.rb +37 -0
- data/lib/openapi3_parser/node_factories/path_item.rb +75 -0
- data/lib/openapi3_parser/node_factories/paths.rb +32 -0
- data/lib/openapi3_parser/node_factories/reference.rb +33 -0
- data/lib/openapi3_parser/node_factories/request_body.rb +31 -0
- data/lib/openapi3_parser/node_factories/response.rb +45 -0
- data/lib/openapi3_parser/node_factories/responses.rb +32 -0
- data/lib/openapi3_parser/node_factories/schema.rb +106 -0
- data/lib/openapi3_parser/node_factories/security_requirement.rb +25 -0
- data/lib/openapi3_parser/node_factories/security_scheme.rb +35 -0
- data/lib/openapi3_parser/node_factories/server.rb +32 -0
- data/lib/openapi3_parser/node_factories/server_variable.rb +28 -0
- data/lib/openapi3_parser/node_factories/tag.rb +24 -0
- data/lib/openapi3_parser/node_factories/xml.rb +25 -0
- data/lib/openapi3_parser/node_factory.rb +126 -0
- data/lib/openapi3_parser/node_factory/field_config.rb +88 -0
- data/lib/openapi3_parser/node_factory/map.rb +39 -0
- data/lib/openapi3_parser/node_factory/object.rb +80 -0
- data/lib/openapi3_parser/node_factory/object/node_builder.rb +85 -0
- data/lib/openapi3_parser/node_factory/object/validator.rb +102 -0
- data/lib/openapi3_parser/node_factory/optional_reference.rb +23 -0
- data/lib/openapi3_parser/nodes/array.rb +26 -0
- data/lib/openapi3_parser/nodes/callback.rb +11 -0
- data/lib/openapi3_parser/nodes/components.rb +47 -0
- data/lib/openapi3_parser/nodes/contact.rb +23 -0
- data/lib/openapi3_parser/nodes/discriminator.rb +19 -0
- data/lib/openapi3_parser/nodes/encoding.rb +31 -0
- data/lib/openapi3_parser/nodes/example.rb +27 -0
- data/lib/openapi3_parser/nodes/external_documentation.rb +19 -0
- data/lib/openapi3_parser/nodes/header.rb +13 -0
- data/lib/openapi3_parser/nodes/info.rb +35 -0
- data/lib/openapi3_parser/nodes/license.rb +19 -0
- data/lib/openapi3_parser/nodes/link.rb +35 -0
- data/lib/openapi3_parser/nodes/map.rb +11 -0
- data/lib/openapi3_parser/nodes/media_type.rb +27 -0
- data/lib/openapi3_parser/nodes/oauth_flow.rb +27 -0
- data/lib/openapi3_parser/nodes/oauth_flows.rb +27 -0
- data/lib/openapi3_parser/nodes/openapi.rb +44 -0
- data/lib/openapi3_parser/nodes/operation.rb +59 -0
- data/lib/openapi3_parser/nodes/parameter.rb +21 -0
- data/lib/openapi3_parser/nodes/parameter/parameter_like.rb +53 -0
- data/lib/openapi3_parser/nodes/path_item.rb +59 -0
- data/lib/openapi3_parser/nodes/paths.rb +11 -0
- data/lib/openapi3_parser/nodes/request_body.rb +23 -0
- data/lib/openapi3_parser/nodes/response.rb +27 -0
- data/lib/openapi3_parser/nodes/responses.rb +15 -0
- data/lib/openapi3_parser/nodes/schema.rb +159 -0
- data/lib/openapi3_parser/nodes/security_requirement.rb +11 -0
- data/lib/openapi3_parser/nodes/security_scheme.rb +44 -0
- data/lib/openapi3_parser/nodes/server.rb +25 -0
- data/lib/openapi3_parser/nodes/server_variable.rb +23 -0
- data/lib/openapi3_parser/nodes/tag.rb +23 -0
- data/lib/openapi3_parser/nodes/xml.rb +31 -0
- data/lib/openapi3_parser/validation/error.rb +14 -0
- data/lib/openapi3_parser/validation/error_collection.rb +36 -0
- data/lib/openapi3_parser/version.rb +5 -0
- data/openapi3_parser.gemspec +28 -0
- metadata +208 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openapi3_parser/node_factory/object/validator"
|
|
4
|
+
require "openapi3_parser/error"
|
|
5
|
+
|
|
6
|
+
module Openapi3Parser
|
|
7
|
+
module NodeFactory
|
|
8
|
+
module Object
|
|
9
|
+
class NodeBuilder
|
|
10
|
+
def initialize(input, factory)
|
|
11
|
+
@input = input
|
|
12
|
+
@factory = factory
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def data
|
|
16
|
+
check_required_fields
|
|
17
|
+
check_unexpected_fields
|
|
18
|
+
check_fields_valid
|
|
19
|
+
data = input.each_with_object({}) do |(key, value), memo|
|
|
20
|
+
memo[key] = value.respond_to?(:node) ? value.node : value
|
|
21
|
+
end
|
|
22
|
+
apply_defaults(data)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
attr_reader :input, :factory
|
|
28
|
+
|
|
29
|
+
def context
|
|
30
|
+
factory.context
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def check_required_fields
|
|
34
|
+
fields = Validator.missing_required_fields(input, factory)
|
|
35
|
+
return if fields.empty?
|
|
36
|
+
raise Openapi3Parser::Error,
|
|
37
|
+
"Missing required fields for "\
|
|
38
|
+
"#{context.stringify_namespace}: #{fields.join(', ')}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def check_unexpected_fields
|
|
42
|
+
fields = Validator.unexpected_fields(input, factory)
|
|
43
|
+
return if fields.empty?
|
|
44
|
+
raise Openapi3Parser::Error,
|
|
45
|
+
"Unexpected fields for #{context.stringify_namespace}: "\
|
|
46
|
+
"#{fields.join(', ')}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def check_fields_valid
|
|
50
|
+
factory.field_configs.each do |name, field_config|
|
|
51
|
+
check_type_error(name, field_config)
|
|
52
|
+
check_validation_errors(name, field_config)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def check_type_error(name, field_config)
|
|
57
|
+
field_context = context.next_namespace(name)
|
|
58
|
+
error = field_config.input_type_error(input[name], factory)
|
|
59
|
+
|
|
60
|
+
return unless error
|
|
61
|
+
raise Openapi3Parser::Error,
|
|
62
|
+
"Invalid type for "\
|
|
63
|
+
"#{field_context.stringify_namespace}: #{error}"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def check_validation_errors(name, field_config)
|
|
67
|
+
field_context = context.next_namespace(name)
|
|
68
|
+
errors = field_config.validation_errors(input[name], factory)
|
|
69
|
+
|
|
70
|
+
return unless errors.any?
|
|
71
|
+
raise Openapi3Parser::Error,
|
|
72
|
+
"Invalid field for #{field_context.stringify_namespace}: "\
|
|
73
|
+
"#{errors.join(', ')}"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def apply_defaults(data)
|
|
77
|
+
configs = factory.field_configs
|
|
78
|
+
configs.each_with_object(data) do |(name, field_config), _memo|
|
|
79
|
+
data[name] = field_config.default(factory) if data[name].nil?
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openapi3_parser/node_factory"
|
|
4
|
+
require "openapi3_parser/validation/error"
|
|
5
|
+
|
|
6
|
+
module Openapi3Parser
|
|
7
|
+
module NodeFactory
|
|
8
|
+
module Object
|
|
9
|
+
class Validator
|
|
10
|
+
def self.missing_required_fields(input, factory)
|
|
11
|
+
configs = factory.field_configs
|
|
12
|
+
configs.each_with_object([]) do |(name, field_config), memo|
|
|
13
|
+
memo << name if field_config.required?(factory) && input[name].nil?
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.unexpected_fields(input, factory)
|
|
18
|
+
unexpected_keys = input.keys - factory.field_configs.keys
|
|
19
|
+
if factory.allowed_extensions?
|
|
20
|
+
unexpected_keys.reject { |k| k =~ NodeFactory::EXTENSION_REGEX }
|
|
21
|
+
else
|
|
22
|
+
unexpected_keys
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def initialize(input, factory)
|
|
27
|
+
@input = input
|
|
28
|
+
@factory = factory
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def errors
|
|
32
|
+
[
|
|
33
|
+
missing_required_fields_error,
|
|
34
|
+
unexpected_fields_error,
|
|
35
|
+
invalid_field_errors
|
|
36
|
+
].flatten.compact
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
attr_reader :input, :factory
|
|
42
|
+
|
|
43
|
+
def context
|
|
44
|
+
factory.context
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def missing_required_fields_error
|
|
48
|
+
fields = self.class.missing_required_fields(input, factory)
|
|
49
|
+
return unless fields.any?
|
|
50
|
+
Validation::Error.new(
|
|
51
|
+
context.namespace,
|
|
52
|
+
"Missing required fields: #{fields.join(', ')}"
|
|
53
|
+
)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def unexpected_fields_error
|
|
57
|
+
fields = self.class.unexpected_fields(input, factory)
|
|
58
|
+
return unless fields.any?
|
|
59
|
+
Validation::Error.new(
|
|
60
|
+
context.namespace,
|
|
61
|
+
"Unexpected fields: #{fields.join(', ')}"
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def invalid_field_errors
|
|
66
|
+
factory.field_configs.inject([]) do |memo, (name, field_config)|
|
|
67
|
+
memo + field_errors(name, field_config)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def field_errors(name, field_config)
|
|
72
|
+
field = input[name]
|
|
73
|
+
return [] if field.nil?
|
|
74
|
+
return field.errors.to_a if field.respond_to?(:errors)
|
|
75
|
+
type_error = build_type_error(name, field_config)
|
|
76
|
+
return [type_error] if type_error
|
|
77
|
+
build_validation_errors(name, field_config)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def build_type_error(name, field_config)
|
|
81
|
+
type_error = field_config.input_type_error(input[name], factory)
|
|
82
|
+
return unless type_error
|
|
83
|
+
Validation::Error.new(
|
|
84
|
+
context.next_namespace(name),
|
|
85
|
+
"Invalid type: #{type_error}"
|
|
86
|
+
)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def build_validation_errors(name, field_config)
|
|
90
|
+
field_config.validation_errors(
|
|
91
|
+
input[name], factory
|
|
92
|
+
).map do |error|
|
|
93
|
+
Validation::Error.new(
|
|
94
|
+
context.next_namespace(name),
|
|
95
|
+
"Invalid field: #{error}"
|
|
96
|
+
)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openapi3_parser/node_factories/reference"
|
|
4
|
+
|
|
5
|
+
module Openapi3Parser
|
|
6
|
+
module NodeFactory
|
|
7
|
+
class OptionalReference
|
|
8
|
+
def initialize(factory)
|
|
9
|
+
@factory = factory
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call(context)
|
|
13
|
+
reference = context.input.is_a?(Hash) && context.input["$ref"]
|
|
14
|
+
return NodeFactories::Reference.new(context, self) if reference
|
|
15
|
+
factory.new(context)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
attr_reader :factory
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openapi3_parser/node/map"
|
|
4
|
+
|
|
5
|
+
module Openapi3Parser
|
|
6
|
+
module Nodes
|
|
7
|
+
class Array
|
|
8
|
+
include Enumerable
|
|
9
|
+
|
|
10
|
+
attr_reader :node_data, :node_context
|
|
11
|
+
|
|
12
|
+
def initialize(data, context)
|
|
13
|
+
@node_data = data
|
|
14
|
+
@node_context = context
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def [](value)
|
|
18
|
+
node_data[value]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def each(&block)
|
|
22
|
+
node_data.each(&block)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openapi3_parser/node/object"
|
|
4
|
+
|
|
5
|
+
module Openapi3Parser
|
|
6
|
+
module Nodes
|
|
7
|
+
class Components
|
|
8
|
+
include Node::Object
|
|
9
|
+
|
|
10
|
+
def schemas
|
|
11
|
+
node_data["schemas"]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def responses
|
|
15
|
+
node_data["responses"]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def parameters
|
|
19
|
+
node_data["parameters"]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def examples
|
|
23
|
+
node_data["examples"]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def request_bodies
|
|
27
|
+
node_data["requestBodies"]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def headers
|
|
31
|
+
node_data["headers"]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def security_schemes
|
|
35
|
+
node_data["securitySchemes"]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def links
|
|
39
|
+
node_data["links"]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def callbacks
|
|
43
|
+
node_data["callbacks"]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openapi3_parser/node/object"
|
|
4
|
+
|
|
5
|
+
module Openapi3Parser
|
|
6
|
+
module Nodes
|
|
7
|
+
class Contact
|
|
8
|
+
include Node::Object
|
|
9
|
+
|
|
10
|
+
def name
|
|
11
|
+
data["name"]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def url
|
|
15
|
+
data["url"]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def email
|
|
19
|
+
data["email"]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openapi3_parser/node/object"
|
|
4
|
+
|
|
5
|
+
module Openapi3Parser
|
|
6
|
+
module Nodes
|
|
7
|
+
class Discriminator
|
|
8
|
+
include Node::Object
|
|
9
|
+
|
|
10
|
+
def property_name
|
|
11
|
+
node_data["propertyName"]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def mapping
|
|
15
|
+
node_data["mapping"]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openapi3_parser/node/object"
|
|
4
|
+
|
|
5
|
+
module Openapi3Parser
|
|
6
|
+
module Nodes
|
|
7
|
+
class Encoding
|
|
8
|
+
include Node::Object
|
|
9
|
+
|
|
10
|
+
def content_type
|
|
11
|
+
node_data["contentType"]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def headers
|
|
15
|
+
node_data["headers"]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def style
|
|
19
|
+
node_data["style"]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def explode?
|
|
23
|
+
node_data["explode"]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def allow_reserved?
|
|
27
|
+
node_data["allowReserved"]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openapi3_parser/node/object"
|
|
4
|
+
|
|
5
|
+
module Openapi3Parser
|
|
6
|
+
module Nodes
|
|
7
|
+
class Example
|
|
8
|
+
include Node::Object
|
|
9
|
+
|
|
10
|
+
def summary
|
|
11
|
+
node_data["summary"]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def description
|
|
15
|
+
node_data["description"]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def value
|
|
19
|
+
node_data["value"]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def external_value
|
|
23
|
+
node_data["externalValue"]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openapi3_parser/node/object"
|
|
4
|
+
|
|
5
|
+
module Openapi3Parser
|
|
6
|
+
module Nodes
|
|
7
|
+
class ExternalDocumentation
|
|
8
|
+
include Node::Object
|
|
9
|
+
|
|
10
|
+
def description
|
|
11
|
+
node_data["description"]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def url
|
|
15
|
+
node_data["url"]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openapi3_parser/node/object"
|
|
4
|
+
require "openapi3_parser/nodes/parameter/parameter_like"
|
|
5
|
+
|
|
6
|
+
module Openapi3Parser
|
|
7
|
+
module Nodes
|
|
8
|
+
class Header
|
|
9
|
+
include Node::Object
|
|
10
|
+
include Parameter::ParameterLike
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "openapi3_parser/node/object"
|
|
4
|
+
|
|
5
|
+
module Openapi3Parser
|
|
6
|
+
module Nodes
|
|
7
|
+
class Info
|
|
8
|
+
include Node::Object
|
|
9
|
+
|
|
10
|
+
def title
|
|
11
|
+
node_data["title"]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def description
|
|
15
|
+
node_data["description"]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def terms_of_service
|
|
19
|
+
node_data["termsOfService"]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def contact
|
|
23
|
+
node_data["contact"]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def license
|
|
27
|
+
node_data["license"]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def version
|
|
31
|
+
node_data["version"]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|