brujula 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +9 -0
- data/Gemfile +5 -0
- data/README.md +64 -0
- data/Rakefile +21 -0
- data/SPEC_SUPPORT.md +183 -0
- data/TODO.md +1 -0
- data/lib/brujula.rb +71 -0
- data/lib/brujula/basic_type.rb +46 -0
- data/lib/brujula/data_transformers/body_declaration.rb +39 -0
- data/lib/brujula/data_transformers/property_declaration.rb +28 -0
- data/lib/brujula/data_transformers/security_scheme_settings_declaration.rb +23 -0
- data/lib/brujula/initializers/inflecto_ramelize.rb +9 -0
- data/lib/brujula/initializers/yaml_include.rb +42 -0
- data/lib/brujula/key.rb +45 -0
- data/lib/brujula/map_object.rb +99 -0
- data/lib/brujula/mergers/map_object_merger.rb +78 -0
- data/lib/brujula/mergers/merger.rb +27 -0
- data/lib/brujula/mergers/object_merger.rb +41 -0
- data/lib/brujula/object.rb +40 -0
- data/lib/brujula/object_builder.rb +114 -0
- data/lib/brujula/object_parser.rb +65 -0
- data/lib/brujula/raml.rb +5 -0
- data/lib/brujula/raml/definition.rb +45 -0
- data/lib/brujula/raml/exceptions.rb +6 -0
- data/lib/brujula/raml/v1_0/array.rb +8 -0
- data/lib/brujula/raml/v1_0/base_uri_parameters.rb +9 -0
- data/lib/brujula/raml/v1_0/body.rb +9 -0
- data/lib/brujula/raml/v1_0/body_type.rb +9 -0
- data/lib/brujula/raml/v1_0/header.rb +9 -0
- data/lib/brujula/raml/v1_0/markdown.rb +8 -0
- data/lib/brujula/raml/v1_0/media_type.rb +8 -0
- data/lib/brujula/raml/v1_0/method.rb +22 -0
- data/lib/brujula/raml/v1_0/null_security_scheme.rb +8 -0
- data/lib/brujula/raml/v1_0/property.rb +34 -0
- data/lib/brujula/raml/v1_0/query_parameter.rb +9 -0
- data/lib/brujula/raml/v1_0/raml_type.rb +37 -0
- data/lib/brujula/raml/v1_0/resource.rb +19 -0
- data/lib/brujula/raml/v1_0/resource_type.rb +15 -0
- data/lib/brujula/raml/v1_0/response.rb +16 -0
- data/lib/brujula/raml/v1_0/root.rb +30 -0
- data/lib/brujula/raml/v1_0/security_scheme.rb +15 -0
- data/lib/brujula/raml/v1_0/security_scheme_part.rb +18 -0
- data/lib/brujula/raml/v1_0/security_scheme_settings.rb +24 -0
- data/lib/brujula/raml/v1_0/string.rb +8 -0
- data/lib/brujula/raml/v1_0/trait.rb +17 -0
- data/lib/brujula/raml/v1_0/uri_parameter.rb +9 -0
- data/lib/brujula/raml/v1_0/uri_template.rb +8 -0
- data/lib/brujula/scheme.rb +77 -0
- data/lib/brujula/type_extender/method.rb +29 -0
- data/lib/brujula/type_extender/resource.rb +52 -0
- data/lib/brujula/type_extender/resource_type.rb +36 -0
- data/lib/brujula/version.rb +3 -0
- data/lib/brujula/yaml_parser.rb +67 -0
- metadata +224 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module Brujula
|
2
|
+
module DataTransformers
|
3
|
+
class PropertyDeclaration
|
4
|
+
class << self
|
5
|
+
def call(*args)
|
6
|
+
new(*args).call
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :data, :parent
|
11
|
+
|
12
|
+
def initialize(parent, data)
|
13
|
+
@parent = parent
|
14
|
+
@data = data
|
15
|
+
end
|
16
|
+
|
17
|
+
def call
|
18
|
+
data.each_with_object({}) do |(key, property), object|
|
19
|
+
if property.is_a?(String) # data as type
|
20
|
+
object.merge!(key => { "type" => property })
|
21
|
+
else
|
22
|
+
object.merge!(key => property)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Brujula
|
2
|
+
module DataTransformers
|
3
|
+
class SecuritySchemeSettingsDeclaration
|
4
|
+
class << self
|
5
|
+
def call(*args)
|
6
|
+
new(*args).call
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :data, :parent
|
11
|
+
|
12
|
+
def initialize(parent, data)
|
13
|
+
@parent = parent
|
14
|
+
@data = data
|
15
|
+
end
|
16
|
+
|
17
|
+
# Add the type from the parent and carry on
|
18
|
+
def call
|
19
|
+
data.merge("type" => parent.type)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
# stolen from https://github.com/coub/raml_ruby/
|
4
|
+
module Brujula
|
5
|
+
class YamlInclude
|
6
|
+
attr_reader :path
|
7
|
+
|
8
|
+
def init_with(coder)
|
9
|
+
@path = coder.scalar
|
10
|
+
end
|
11
|
+
|
12
|
+
def load_external_data(base_dir)
|
13
|
+
YAML.load external_data_content(base_dir)
|
14
|
+
end
|
15
|
+
|
16
|
+
def parseable?
|
17
|
+
parseable_extensions.include?(path_extension)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def external_data_content(base_dir)
|
23
|
+
File.read(external_data_path(base_dir))
|
24
|
+
end
|
25
|
+
|
26
|
+
def external_data_path(base_dir)
|
27
|
+
return path if path.start_with?('/') # absolute path reference
|
28
|
+
|
29
|
+
File.join(base_dir, path)
|
30
|
+
end
|
31
|
+
|
32
|
+
def path_extension
|
33
|
+
File.extname(path)
|
34
|
+
end
|
35
|
+
|
36
|
+
def parseable_extensions
|
37
|
+
%w( .yaml .yml .raml )
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
YAML.add_tag '!include', Brujula::YamlInclude
|
data/lib/brujula/key.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Brujula
|
2
|
+
class Key
|
3
|
+
attr_reader :expression, :required, :options, :for_types, :referrable,
|
4
|
+
:data_transformer, :name
|
5
|
+
|
6
|
+
alias_method :required?, :required
|
7
|
+
alias_method :referrable?, :referrable
|
8
|
+
|
9
|
+
def initialize(expression, options)
|
10
|
+
@expression = expression
|
11
|
+
@name = expression.to_s
|
12
|
+
@options = options
|
13
|
+
@required = !!options[:required]
|
14
|
+
@referrable = !!options[:referrable]
|
15
|
+
@for_types = options[:for_types] || []
|
16
|
+
@data_transformer = options[:data_transformer]
|
17
|
+
end
|
18
|
+
|
19
|
+
def accessor_name
|
20
|
+
options[:accessor] || expression
|
21
|
+
end
|
22
|
+
|
23
|
+
def fixed?
|
24
|
+
expression.is_a?(Symbol)
|
25
|
+
end
|
26
|
+
|
27
|
+
def matches?(key_name)
|
28
|
+
!(expression =~ key_name).nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
def valid_for_type?(type)
|
32
|
+
return true if for_types.empty?
|
33
|
+
|
34
|
+
for_types.include?(type)
|
35
|
+
end
|
36
|
+
|
37
|
+
def basic_type?
|
38
|
+
basic_types.include?(options[:as])
|
39
|
+
end
|
40
|
+
|
41
|
+
def basic_types
|
42
|
+
%i( any array boolean markdown media_type number string uri_template )
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Brujula
|
2
|
+
class MapObject
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_reader :parent, :name, :child_class
|
6
|
+
|
7
|
+
def initialize(data:, parent: nil, name:, child_class:)
|
8
|
+
@parent = parent
|
9
|
+
@name = name
|
10
|
+
@child_class = child_class
|
11
|
+
@collection = {}
|
12
|
+
each_flatted_child(data) do |child_name, child_data|
|
13
|
+
child_object = build_object(child_name, child_data)
|
14
|
+
|
15
|
+
@collection.merge!(child_name.to_s => child_object)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def key?(key)
|
20
|
+
@collection.key?(key.to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
def [](key)
|
24
|
+
@collection.fetch(key.to_s, nil)
|
25
|
+
end
|
26
|
+
|
27
|
+
def fetch(key)
|
28
|
+
@collection.fetch(key.to_s)
|
29
|
+
rescue KeyError => error
|
30
|
+
$stderr.puts "Couldn't find item #{ key } in collection #{ name }"
|
31
|
+
raise error
|
32
|
+
end
|
33
|
+
|
34
|
+
def merge(key, value)
|
35
|
+
@collection.merge!(key.to_s => value)
|
36
|
+
end
|
37
|
+
|
38
|
+
def each
|
39
|
+
@collection.values.each { |item| yield item }
|
40
|
+
end
|
41
|
+
|
42
|
+
def expand
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def build_object(name, data)
|
49
|
+
child_data = normalize_child_data(data)
|
50
|
+
options = { data: child_data, name: name, parent: self }
|
51
|
+
object = child_klass.new(options)
|
52
|
+
apply_inheritance(object)
|
53
|
+
end
|
54
|
+
|
55
|
+
def child_klass
|
56
|
+
Brujula::Raml::V1_0.const_get(Inflecto.camelize(child_class))
|
57
|
+
end
|
58
|
+
|
59
|
+
def normalize_child_data(data)
|
60
|
+
return data unless data.is_a?(Brujula::YamlInclude)
|
61
|
+
|
62
|
+
data.load_external_data(parent.root.base_dir)
|
63
|
+
end
|
64
|
+
|
65
|
+
def apply_inheritance(child)
|
66
|
+
case child
|
67
|
+
when Brujula::Raml::V1_0::Resource
|
68
|
+
Brujula::TypeExtender::Resource.new(definition: child).call
|
69
|
+
when Brujula::Raml::V1_0::Method
|
70
|
+
Brujula::TypeExtender::Method.new(definition: child).call
|
71
|
+
when Brujula::Raml::V1_0::ResourceType
|
72
|
+
Brujula::TypeExtender::ResourceType.new(definition: child).call
|
73
|
+
else
|
74
|
+
child
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def each_flatted_child(data)
|
79
|
+
flatten_children(data).each do |child_name, child_data|
|
80
|
+
yield child_name, child_data
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def flatten_children(data)
|
85
|
+
case data
|
86
|
+
when Array
|
87
|
+
data.each_with_object({}) do |child, children|
|
88
|
+
child.each do |key, value|
|
89
|
+
children.merge!(key => value)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
when Hash
|
93
|
+
data
|
94
|
+
else
|
95
|
+
raise 'Invalid data for map_object'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Brujula
|
2
|
+
module Mergers
|
3
|
+
class MapObjectMerger
|
4
|
+
attr_reader :superinstance, :instance
|
5
|
+
|
6
|
+
def initialize(instance:, superinstance:)
|
7
|
+
@superinstance = superinstance
|
8
|
+
@instance = instance
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
return superinstance.dup if instance.nil?
|
13
|
+
|
14
|
+
instance.dup.tap do |extended_instance|
|
15
|
+
each_inheritable_items do |inherit_item|
|
16
|
+
extended_instance.merge(inherit_item.name, inherit_item)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def each_inheritable_items
|
22
|
+
superinstance.each do |inherit_item|
|
23
|
+
|
24
|
+
merge_item = case item_reference(inherit_item.name)
|
25
|
+
when :optional_to_optional
|
26
|
+
instance.fetch(inherit_item.name)
|
27
|
+
when :optional
|
28
|
+
instance.fetch(inherit_item.name.gsub(/\?$/, ''))
|
29
|
+
when :direct
|
30
|
+
instance.key?(inherit_item.name) ?
|
31
|
+
instance.fetch(inherit_item.name) : nil
|
32
|
+
else
|
33
|
+
next
|
34
|
+
end
|
35
|
+
|
36
|
+
yield merger(merge_item, inherit_item)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def merger(merge_item, inherit_item)
|
41
|
+
Merger.new(instance: merge_item, superinstance: inherit_item).call
|
42
|
+
end
|
43
|
+
|
44
|
+
def item_reference(key)
|
45
|
+
case
|
46
|
+
when optional_key?(key) && instance_has_optional_item?(key)
|
47
|
+
:optional_to_optional
|
48
|
+
when optional_key?(key) && instance_has_item?(key)
|
49
|
+
:optional
|
50
|
+
when !optional_key?(key)
|
51
|
+
:direct
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def merge_item?(key)
|
56
|
+
return true unless optional_key?(key)
|
57
|
+
|
58
|
+
instance_has_item?(key) || instance_has_optional_item?(key)
|
59
|
+
end
|
60
|
+
|
61
|
+
def optional_key?(key)
|
62
|
+
key.to_s.end_with?('?')
|
63
|
+
end
|
64
|
+
|
65
|
+
def instance_has_item?(key)
|
66
|
+
item_names.include?(key.gsub(/\?$/, ''))
|
67
|
+
end
|
68
|
+
|
69
|
+
def instance_has_optional_item?(key)
|
70
|
+
item_names.include?(key)
|
71
|
+
end
|
72
|
+
|
73
|
+
def item_names
|
74
|
+
@item_names ||= instance.to_a.map(&:name)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Brujula
|
2
|
+
module Mergers
|
3
|
+
class Merger
|
4
|
+
attr_reader :superinstance, :instance
|
5
|
+
|
6
|
+
def initialize(instance:, superinstance:)
|
7
|
+
@superinstance = superinstance
|
8
|
+
@instance = instance
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
case
|
13
|
+
when superinstance.is_a?(Brujula::MapObject)
|
14
|
+
MapObjectMerger.new(
|
15
|
+
instance: instance, superinstance: superinstance
|
16
|
+
).call
|
17
|
+
when superinstance.is_a?(Brujula::Object)
|
18
|
+
ObjectMerger.new(
|
19
|
+
instance: instance, superinstance: superinstance
|
20
|
+
).call
|
21
|
+
else
|
22
|
+
superinstance.dup
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Brujula
|
2
|
+
module Mergers
|
3
|
+
class ObjectMerger
|
4
|
+
attr_reader :superinstance, :instance
|
5
|
+
|
6
|
+
def initialize(instance:, superinstance:)
|
7
|
+
@superinstance = superinstance
|
8
|
+
@instance = instance
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
return superinstance.dup if instance.nil?
|
13
|
+
instance.dup.tap do |object|
|
14
|
+
each_inheritable_attributes do |name, attribute|
|
15
|
+
original_item = object.instance_variable_get("@#{ name }")
|
16
|
+
thing = Merger.new(
|
17
|
+
instance: original_item, superinstance: attribute
|
18
|
+
).call
|
19
|
+
object.instance_variable_set("@#{ name }", thing)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def each_inheritable_attributes
|
25
|
+
applicable_attributes.each do |name|
|
26
|
+
next if superinstance.instance_variable_get(name).nil?
|
27
|
+
string_name = name.to_s.gsub(/^@/, '')
|
28
|
+
yield(string_name, superinstance.instance_variable_get(name))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def applicable_attributes
|
33
|
+
superinstance.instance_variables - excluded_attributes
|
34
|
+
end
|
35
|
+
|
36
|
+
def excluded_attributes
|
37
|
+
%i( @parent @name @type )
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Brujula
|
2
|
+
class Object
|
3
|
+
attr_reader :name
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_reader :scheme, :block
|
7
|
+
|
8
|
+
def scheme(options = {}, &block) # TODO
|
9
|
+
return @scheme unless @scheme.nil?
|
10
|
+
|
11
|
+
if block_given?
|
12
|
+
@block = block
|
13
|
+
@scheme = Brujula::Scheme.new(self, options, block)
|
14
|
+
else
|
15
|
+
@scheme = Brujula::Scheme.new(self, options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(data:, parent: nil, name:)
|
21
|
+
@name = name
|
22
|
+
define_singleton_method(:raw_data) { data }
|
23
|
+
define_singleton_method(:parent) { parent }
|
24
|
+
|
25
|
+
Brujula::ObjectParser.call(definition: self, data: data, parent: parent)
|
26
|
+
end
|
27
|
+
|
28
|
+
def expand # TODO
|
29
|
+
@representation || self
|
30
|
+
end
|
31
|
+
|
32
|
+
def root
|
33
|
+
object = self
|
34
|
+
until object.is_a? Brujula::Raml::V1_0::Root
|
35
|
+
object = object.parent
|
36
|
+
end
|
37
|
+
object
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|