raml_parser 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +7 -0
- data/lib/raml_parser.rb +270 -0
- data/lib/raml_parser/model.rb +146 -0
- data/lib/raml_parser/version.rb +3 -0
- data/lib/raml_parser/yaml_helper.rb +122 -0
- data/raml_parser.gemspec +26 -0
- data/spec/examples/raml/documentation.raml +11 -0
- data/spec/examples/raml/external/box.raml +8473 -0
- data/spec/examples/raml/external/bug.raml +12 -0
- data/spec/examples/raml/external/github.raml +21650 -0
- data/spec/examples/raml/external/groups_and_nesting.raml +22 -0
- data/spec/examples/raml/external/instagram.yml +3369 -0
- data/spec/examples/raml/external/json_schema.json +18 -0
- data/spec/examples/raml/external/jukebox-api.raml +191 -0
- data/spec/examples/raml/external/jukebox-include-album-new.sample +8 -0
- data/spec/examples/raml/external/jukebox-include-album-retrieve.sample +30 -0
- data/spec/examples/raml/external/jukebox-include-album-songs.sample +14 -0
- data/spec/examples/raml/external/jukebox-include-album.schema +36 -0
- data/spec/examples/raml/external/jukebox-include-albums.sample +32 -0
- data/spec/examples/raml/external/jukebox-include-artist-albums.sample +42 -0
- data/spec/examples/raml/external/jukebox-include-artist-new.sample +5 -0
- data/spec/examples/raml/external/jukebox-include-artist-retrieve.sample +52 -0
- data/spec/examples/raml/external/jukebox-include-artist.schema +20 -0
- data/spec/examples/raml/external/jukebox-include-artists.sample +32 -0
- data/spec/examples/raml/external/jukebox-include-song-new.sample +5 -0
- data/spec/examples/raml/external/jukebox-include-song-retrieve.sample +15 -0
- data/spec/examples/raml/external/jukebox-include-song.schema +24 -0
- data/spec/examples/raml/external/jukebox-include-songs.sample +14 -0
- data/spec/examples/raml/external/linkedin-v1-single.yml +2671 -0
- data/spec/examples/raml/external/mule_sales_enablement.raml +148 -0
- data/spec/examples/raml/external/multiple-methods.raml +11 -0
- data/spec/examples/raml/external/named_parameters.raml +85 -0
- data/spec/examples/raml/external/requests-responses.raml +47 -0
- data/spec/examples/raml/external/resource_summary_spacing.raml +42 -0
- data/spec/examples/raml/external/simple.raml +233 -0
- data/spec/examples/raml/external/stripe.raml +12226 -0
- data/spec/examples/raml/external/test.raml +11 -0
- data/spec/examples/raml/external/twitter.raml +34284 -0
- data/spec/examples/raml/external/xml_example.xml +25 -0
- data/spec/examples/raml/external/xml_schema.xsd +50 -0
- data/spec/examples/raml/formparameters.raml +23 -0
- data/spec/examples/raml/headers.raml +15 -0
- data/spec/examples/raml/issue2.raml +51 -0
- data/spec/examples/raml/methods.raml +9 -0
- data/spec/examples/raml/parameters.raml +21 -0
- data/spec/examples/raml/parametersinflection.raml +21 -0
- data/spec/examples/raml/queryparameters.raml +14 -0
- data/spec/examples/raml/requestbodies.raml +21 -0
- data/spec/examples/raml/resources.raml +15 -0
- data/spec/examples/raml/resourcetypes.raml +16 -0
- data/spec/examples/raml/responses.raml +25 -0
- data/spec/examples/raml/securedby1.raml +20 -0
- data/spec/examples/raml/securedby2.raml +21 -0
- data/spec/examples/raml/securityschemes.raml +47 -0
- data/spec/examples/raml/simple.raml +6 -0
- data/spec/examples/raml/traits.raml +34 -0
- data/spec/examples/raml/uriparameters.raml +16 -0
- data/spec/examples/yaml/include1.yml +2 -0
- data/spec/examples/yaml/include2.yml +1 -0
- data/spec/examples/yaml/simple.yml +2 -0
- data/spec/examples/yaml/traversing.yml +11 -0
- data/spec/lib/raml_parser/yaml_parser_spec.rb +38 -0
- data/spec/lib/raml_parser_spec.rb +196 -0
- data/spec/spec_helper.rb +91 -0
- metadata +229 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 15632f30b43baa8f09f37bb3f06b10fee158f138
|
4
|
+
data.tar.gz: 87d3a333ef6dbb848da083db0f344e9e0041a404
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 251ac847b813be9b1bea013ded667d10208d377b56f75edae87bce4fe5a352ca3f8d94f3fea44297c9527ce6b227521ad4eeded792eadcf2b96acb8c2d2b770a
|
7
|
+
data.tar.gz: 6fbf700a78e581c13ebf1248621fe7c280215580651f8096c974ee80f9b0e3fbff78fa4feb61bc8017879c3d2a1ce8ef8eb8c5ba567cd623dfa127175efdf0c1
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Christian Hoffmeister
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# RamlParser
|
2
|
+
|
3
|
+
[![build](https://img.shields.io/travis/ePages-de/raml_parser/develop.svg)](https://travis-ci.org/ePages-de/raml_parser)
|
4
|
+
[![license](http://img.shields.io/badge/license-MIT-lightgrey.svg)](http://opensource.org/licenses/MIT)
|
5
|
+
|
6
|
+
A parser for the [RAML](http://raml.org/) API modeling language.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'raml_parser', :git => 'https://github.com/ePages-de/raml_parser.git', :branch => 'master'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
TODO: Write usage instructions here
|
23
|
+
|
24
|
+
## What parts of RAML are not supported
|
25
|
+
|
26
|
+
These are features of the RAML 0.8 specification that are not fully handled yet. This list should be complete, i.e. everything not listed here should work.
|
27
|
+
|
28
|
+
* [Base URI Parameters](http://raml.org/spec.html#base-uri-parameters)
|
29
|
+
* [Schemas](http://raml.org/spec.html#schemas)
|
30
|
+
* [Protocols](http://raml.org/spec.html#protocols)
|
31
|
+
* [Named parameters with multiple types](http://raml.org/spec.html#named-parameters-with-multiple-types)
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
1. Fork it ( https://github.com/ePages-de/raml_parser/fork )
|
36
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
37
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
38
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
39
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/raml_parser.rb
ADDED
@@ -0,0 +1,270 @@
|
|
1
|
+
require 'raml_parser/yaml_helper'
|
2
|
+
require 'raml_parser/model'
|
3
|
+
|
4
|
+
module RamlParser
|
5
|
+
class Parser
|
6
|
+
attr_reader :path, :root
|
7
|
+
|
8
|
+
def self.parse_file(path)
|
9
|
+
node = YamlNode.new(nil, 'root', YamlHelper.read_yaml(path))
|
10
|
+
parse_root(node)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.parse_file_with_marks(path)
|
14
|
+
node = YamlNode.new(nil, 'root', YamlHelper.read_yaml(path))
|
15
|
+
node.mark_all(:unused)
|
16
|
+
node.mark(:used)
|
17
|
+
root = parse_root(node)
|
18
|
+
{ :root => root, :marks => node.marks }
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def self.parse_root(node)
|
24
|
+
node.hash('schemas').mark_all(:unsupported) if node.value.has_key? 'schemas'
|
25
|
+
|
26
|
+
root = Model::Root.new
|
27
|
+
root.title = node.hash('title').or_default('').value
|
28
|
+
root.base_uri = node.hash('baseUri').or_default('').value
|
29
|
+
root.version = node.hash('version').value
|
30
|
+
root.media_type = node.hash('mediaType').value
|
31
|
+
root.secured_by = node.hash('securedBy').or_default([]).array_map { |n| n.value }
|
32
|
+
root.documentation = node.hash('documentation').array_map { |n| parse_documenation(n) }
|
33
|
+
root.security_schemes = node.hash('securitySchemes').arrayhash_map { |n| parse_security_scheme(n) }
|
34
|
+
root.resource_types = node.hash('resourceTypes').mark_all(:used).arrayhash_map { |n| n }
|
35
|
+
root.traits = node.hash('traits').mark_all(:used).arrayhash_map { |n| n }
|
36
|
+
|
37
|
+
root.resources = traverse_resources(node, nil) do |n,parent|
|
38
|
+
parent_absolute_uri = parent != nil ? parent.absolute_uri : root.base_uri || ''
|
39
|
+
parent_relative_uri = parent != nil ? parent.relative_uri : ''
|
40
|
+
parent_uri_parameters = parent != nil ? parent.uri_parameters.clone : {}
|
41
|
+
parse_resource(n, root, parent_absolute_uri, parent_relative_uri, parent_uri_parameters, false)
|
42
|
+
end
|
43
|
+
|
44
|
+
root
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.parse_resource(node, root, parent_absolute_uri, parent_relative_uri, parent_uri_parameters, as_resource_type)
|
48
|
+
def self.extract_uri_parameters(relative_uri)
|
49
|
+
names = relative_uri.scan(/\{([a-zA-Z\_\-]+)\}/).map { |m| m.first }
|
50
|
+
Hash[names.map { |name| [name, Model::NamedParameter.new(name, 'string', name)] }]
|
51
|
+
end
|
52
|
+
|
53
|
+
node = node.or_default({})
|
54
|
+
resource = Model::Resource.new(parent_absolute_uri + node.key, parent_relative_uri + node.key)
|
55
|
+
resource.display_name = node.hash('displayName').value
|
56
|
+
resource.description = node.hash('description').value
|
57
|
+
resource.uri_parameters = extract_uri_parameters(node.key).merge(parent_uri_parameters.merge(node.hash('uriParameters').hash_map { |n| parse_named_parameter(n) }))
|
58
|
+
resource.type = parse_type(node.hash('type'))
|
59
|
+
resource.is = parse_is(node.hash('is'))
|
60
|
+
resource.secured_by = (root.secured_by + node.hash('securedBy').or_default([]).array_map { |n| n.value }).uniq
|
61
|
+
|
62
|
+
for m in %w(get post put delete head patch options trace connect) do
|
63
|
+
if node.value.has_key? m
|
64
|
+
resource.methods[m] = parse_method(node.hash(m), root, resource, as_resource_type)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
unless as_resource_type
|
69
|
+
resource = mixin_resource_types(node, root, resource)
|
70
|
+
resource.display_name = resource.relative_uri unless resource.display_name
|
71
|
+
end
|
72
|
+
|
73
|
+
resource
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.parse_method(node, root, resource, as_trait)
|
77
|
+
node = node.or_default({})
|
78
|
+
method = Model::Method.new(node.key.upcase)
|
79
|
+
method.display_name = node.hash('displayName').value
|
80
|
+
method.description = node.hash('description').value
|
81
|
+
method.query_parameters = node.hash('queryParameters').hash_map { |n| parse_named_parameter(n) }
|
82
|
+
method.bodies = node.hash('body').hash_map { |n| parse_body(n) }
|
83
|
+
method.responses = node.hash('responses').hash_map { |n| parse_response(n) }
|
84
|
+
method.headers = node.hash('headers').hash_map { |n| parse_named_parameter(n) }
|
85
|
+
method.secured_by = (resource.secured_by + node.hash('securedBy').or_default([]).array_map { |n| n.value }).uniq if resource
|
86
|
+
method.is = parse_is(node.hash('is'))
|
87
|
+
|
88
|
+
unless as_trait
|
89
|
+
method = mixin_traits(node, root, method, resource)
|
90
|
+
method.display_name = method.method + ' ' + resource.relative_uri unless method.display_name
|
91
|
+
end
|
92
|
+
|
93
|
+
method
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.parse_response(node)
|
97
|
+
node = node.or_default({})
|
98
|
+
response = Model::Response.new(node.key)
|
99
|
+
response.display_name = node.hash('displayName').value
|
100
|
+
response.description = node.hash('description').value
|
101
|
+
response.bodies = node.hash('body').hash_map { |n| parse_body(n) }
|
102
|
+
response.headers = node.hash('headers').hash_map { |n| parse_named_parameter(n) }
|
103
|
+
response
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.parse_named_parameter(node)
|
107
|
+
if node.value.is_a? Array
|
108
|
+
node.mark_all(:unsupported)
|
109
|
+
# TODO: Not yet supported named parameters with multiple types
|
110
|
+
return Model::NamedParameter.new(node.key)
|
111
|
+
end
|
112
|
+
|
113
|
+
node = node.or_default({})
|
114
|
+
named_parameter = Model::NamedParameter.new(node.key)
|
115
|
+
named_parameter.type = node.hash('type').or_default('string').value
|
116
|
+
named_parameter.display_name = node.hash('displayName').or_default(named_parameter.name).value
|
117
|
+
named_parameter.description = node.hash('description').value
|
118
|
+
named_parameter.required = node.hash('required').or_default(true).value
|
119
|
+
named_parameter.default = node.hash('default').value
|
120
|
+
named_parameter.example = node.hash('example').value
|
121
|
+
named_parameter.min_length = node.hash('minLength').value
|
122
|
+
named_parameter.max_length = node.hash('maxLength').value
|
123
|
+
named_parameter.minimum = node.hash('minimum').value
|
124
|
+
named_parameter.maximum = node.hash('maximum').value
|
125
|
+
named_parameter.repeat = node.hash('repeat').value
|
126
|
+
named_parameter.enum = node.hash('enum').or_default([]).array_map { |n| n.value }
|
127
|
+
named_parameter.pattern = node.hash('pattern').value
|
128
|
+
named_parameter
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.parse_body(node)
|
132
|
+
node = node.or_default({})
|
133
|
+
body = Model::Body.new(node.key)
|
134
|
+
body.example = node.hash('example').value
|
135
|
+
body.schema = node.hash('schema').value
|
136
|
+
body.form_parameters = node.hash('formParameters').hash_map { |n| parse_named_parameter(n) }
|
137
|
+
# TODO: Form parameters are only allowed for media type application/x-www-form-urlencoded or multipart/form-data
|
138
|
+
body
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.parse_security_scheme(node)
|
142
|
+
node.hash('describedBy').mark_all(:unsupported) if node.value.has_key? 'describedBy'
|
143
|
+
|
144
|
+
node = node.or_default({})
|
145
|
+
security_scheme = Model::SecurityScheme.new(node.key)
|
146
|
+
security_scheme.type = node.hash('type').value
|
147
|
+
security_scheme.description = node.hash('description').value
|
148
|
+
security_scheme.described_by = node.hash('describedBy').value
|
149
|
+
security_scheme.settings = node.hash('settings').mark_all(:used).value
|
150
|
+
security_scheme
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.parse_documenation(node)
|
154
|
+
node = node.or_default({})
|
155
|
+
documentation = Model::Documentation.new
|
156
|
+
documentation.title = node.hash('title').value
|
157
|
+
documentation.content = node.hash('content').value
|
158
|
+
documentation
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.parse_type(node)
|
162
|
+
node = node.or_default({}).mark_all(:used)
|
163
|
+
result = {}
|
164
|
+
if node.value.is_a? String
|
165
|
+
result = { node.value => nil }
|
166
|
+
elsif node.value.is_a? Hash
|
167
|
+
result = node.value
|
168
|
+
else
|
169
|
+
raise "Invalid syntax for 'type' property at #{node.path}"
|
170
|
+
end
|
171
|
+
result
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.parse_is(node)
|
175
|
+
node = node.or_default({}).mark_all(:used)
|
176
|
+
result = {}
|
177
|
+
node.value.each { |n|
|
178
|
+
if n.is_a? String
|
179
|
+
result = result.merge({ n => nil })
|
180
|
+
elsif n.is_a? Hash
|
181
|
+
result = result.merge(n)
|
182
|
+
else
|
183
|
+
raise "Invalid syntax for 'is' property at #{node.path}"
|
184
|
+
end
|
185
|
+
}
|
186
|
+
result
|
187
|
+
end
|
188
|
+
|
189
|
+
def self.mixin_resource_types(node, root, resource)
|
190
|
+
result = Model::Resource.new(nil, nil)
|
191
|
+
resource.type.each do |name,value|
|
192
|
+
params = (value || {}).merge({
|
193
|
+
'resourcePath' => resource.relative_uri,
|
194
|
+
'resourcePathName' => resource.relative_uri.match(/[^\/]*$/).to_s
|
195
|
+
})
|
196
|
+
resource_type = root.resource_types.has_key?(name) ? parse_resource(resolve_parametrization(root.resource_types[name], params), root, '', '', {}, true) : nil
|
197
|
+
if resource_type != nil
|
198
|
+
result = Model::Resource.merge(result, resource_type)
|
199
|
+
else
|
200
|
+
raise "Referencing unknown resource type #{name} at #{node.path}"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
Model::Resource.merge(result, resource)
|
205
|
+
end
|
206
|
+
|
207
|
+
def self.mixin_traits(node, root, method, resource)
|
208
|
+
result = Model::Method.new(nil)
|
209
|
+
(resource.is.merge(method.is)).each do |name,value|
|
210
|
+
params = (value || {}).merge({
|
211
|
+
'resourcePath' => resource.relative_uri,
|
212
|
+
'resourcePathName' => resource.relative_uri.match(/[^\/]*$/).to_s,
|
213
|
+
'methodName' => method.method.downcase
|
214
|
+
})
|
215
|
+
trait = root.traits.has_key?(name) ? parse_method(resolve_parametrization(root.traits[name], params), root, nil, true) : nil
|
216
|
+
if trait != nil
|
217
|
+
result = Model::Method.merge(result, trait)
|
218
|
+
else
|
219
|
+
raise "Referencing unknown trait #{name} at #{node.path}"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
Model::Method.merge(result, method)
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.resolve_parametrization(node, params)
|
227
|
+
require 'active_support/core_ext/string/inflections'
|
228
|
+
|
229
|
+
def self.alter_string(str, params, node)
|
230
|
+
str.gsub(/<<([a-zA-Z]+)(\s*\|\s*!([a-zA-Z_\-]+))?>>/) do |a,b|
|
231
|
+
case $3
|
232
|
+
when nil
|
233
|
+
params[$1].to_s
|
234
|
+
when 'singularize'
|
235
|
+
params[$1].to_s.singularize
|
236
|
+
when 'pluralize'
|
237
|
+
params[$1].to_s.pluralize
|
238
|
+
else
|
239
|
+
raise "Using unknown parametrization function #{$3} at #{node.path}"
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def self.traverse(raw, params, node)
|
245
|
+
if raw.is_a? Hash
|
246
|
+
Hash[raw.map { |k,v| [traverse(k, params, node), traverse(v, params, node)] }]
|
247
|
+
elsif raw.is_a? Array
|
248
|
+
raw.map { |i| traverse(i, params, node) }
|
249
|
+
elsif raw.is_a? String
|
250
|
+
alter_string(raw, params, node)
|
251
|
+
else
|
252
|
+
raw
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
YamlNode.new(node.parent, node.key, traverse(node.value, params, node))
|
257
|
+
end
|
258
|
+
|
259
|
+
def self.traverse_resources(node, parent_resource, &code)
|
260
|
+
node.hash_map { |n|
|
261
|
+
if n.key =~ /^\//
|
262
|
+
resource = code.call(n, parent_resource)
|
263
|
+
[resource] + traverse_resources(n, resource, &code)
|
264
|
+
else
|
265
|
+
[]
|
266
|
+
end
|
267
|
+
}.values.flatten
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module RamlParser
|
2
|
+
module Model
|
3
|
+
class Root
|
4
|
+
attr_accessor :title, :base_uri, :version, :media_type, :security_schemes, :resource_types, :traits, :secured_by, :documentation, :resources
|
5
|
+
|
6
|
+
def initialize(title = nil, base_uri = nil, version = nil, media_type = nil, security_schemes = {}, resource_types = {}, traits = {}, secured_by = [], documentation = [], resources = [])
|
7
|
+
@title = title
|
8
|
+
@base_uri = base_uri
|
9
|
+
@version = version
|
10
|
+
@media_type = media_type
|
11
|
+
@security_schemes = security_schemes
|
12
|
+
@resource_types = resource_types
|
13
|
+
@traits = traits
|
14
|
+
@secured_by = secured_by
|
15
|
+
@documentation = documentation
|
16
|
+
@resources = resources
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Resource
|
21
|
+
attr_accessor :absolute_uri, :relative_uri, :display_name, :description, :uri_parameters, :methods, :type, :is, :secured_by
|
22
|
+
|
23
|
+
def initialize(absolute_uri, relative_uri, display_name = nil, description = nil, uri_parameters = {}, methods = {}, type = {}, is = {}, secured_by = [])
|
24
|
+
@absolute_uri = absolute_uri
|
25
|
+
@relative_uri = relative_uri
|
26
|
+
@display_name = display_name
|
27
|
+
@description = description
|
28
|
+
@uri_parameters = uri_parameters
|
29
|
+
@methods = methods
|
30
|
+
@type = type
|
31
|
+
@is = is
|
32
|
+
@secured_by = secured_by
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.merge(a, b)
|
36
|
+
resource = Resource.new(b.absolute_uri, b.relative_uri)
|
37
|
+
|
38
|
+
resource.display_name = if b.display_name then b.display_name else a.display_name end
|
39
|
+
resource.description = if b.description then b.description else a.description end
|
40
|
+
resource.uri_parameters = a.uri_parameters.merge(b.uri_parameters)
|
41
|
+
resource.methods = a.methods.merge(b.methods)
|
42
|
+
resource.type = a.type.merge(b.type)
|
43
|
+
resource.is = a.is.merge(b.is)
|
44
|
+
resource.secured_by = (a.secured_by + b.secured_by).uniq
|
45
|
+
|
46
|
+
resource
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Method
|
51
|
+
attr_accessor :method, :display_name, :description, :query_parameters, :responses, :bodies, :headers, :is, :secured_by
|
52
|
+
|
53
|
+
def initialize(method, display_name = nil, description = nil, query_parameters = {}, responses = {}, bodies = {}, headers = {}, is = {}, secured_by = [])
|
54
|
+
@method = method
|
55
|
+
@display_name = display_name
|
56
|
+
@description = description
|
57
|
+
@query_parameters = query_parameters
|
58
|
+
@responses = responses
|
59
|
+
@bodies = bodies
|
60
|
+
@headers = headers
|
61
|
+
@is = is
|
62
|
+
@secured_by = secured_by
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.merge(a, b)
|
66
|
+
method = Method.new(b.method)
|
67
|
+
|
68
|
+
method.display_name = if b.display_name then b.display_name else a.display_name end
|
69
|
+
method.description = if b.description then b.description else a.description end
|
70
|
+
method.query_parameters = a.query_parameters.merge(b.query_parameters)
|
71
|
+
method.responses = a.responses.merge(b.responses)
|
72
|
+
method.bodies = a.bodies.merge(b.bodies)
|
73
|
+
method.headers = a.headers.merge(b.headers)
|
74
|
+
method.is = a.is.merge(b.is)
|
75
|
+
method.secured_by = (a.secured_by + b.secured_by).uniq
|
76
|
+
|
77
|
+
method
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class Response
|
82
|
+
attr_accessor :status_code, :display_name, :description, :bodies, :headers
|
83
|
+
|
84
|
+
def initialize(status_code, display_name = nil, description = nil, bodies = {}, headers = {})
|
85
|
+
@status_code = status_code
|
86
|
+
@display_name = display_name
|
87
|
+
@description = description
|
88
|
+
@bodies = bodies
|
89
|
+
@headers = headers
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class Body
|
94
|
+
attr_accessor :media_type, :example, :schema, :form_parameters
|
95
|
+
|
96
|
+
def initialize(media_type, example = nil, schema = nil, form_parameters = {})
|
97
|
+
@media_type = media_type
|
98
|
+
@example = example
|
99
|
+
@schema = schema
|
100
|
+
@form_parameters = form_parameters
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class NamedParameter
|
105
|
+
attr_accessor :name, :type, :display_name, :description, :required, :default, :example, :min_length, :max_length, :minimum, :maximum, :repeat, :enum, :pattern
|
106
|
+
|
107
|
+
def initialize(name, type = nil, display_name = nil, description = nil, required = false, default = nil, example = nil, min_length = nil, max_length = nil, minimum = nil, maximum = nil, repeat = nil, enum = nil, pattern = nil)
|
108
|
+
@name = name
|
109
|
+
@type = type
|
110
|
+
@display_name = display_name
|
111
|
+
@description = description
|
112
|
+
@required = required
|
113
|
+
@default = default
|
114
|
+
@example = example
|
115
|
+
@min_length = min_length
|
116
|
+
@max_length = max_length
|
117
|
+
@minimum = minimum
|
118
|
+
@maximum = maximum
|
119
|
+
@repeat = repeat
|
120
|
+
@enum = enum
|
121
|
+
@pattern = pattern
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class Documentation
|
126
|
+
attr_accessor :title, :content
|
127
|
+
|
128
|
+
def initialize(title = nil, content = nil)
|
129
|
+
@title = title
|
130
|
+
@content = content
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class SecurityScheme
|
135
|
+
attr_accessor :name, :type, :description, :described_by, :settings
|
136
|
+
|
137
|
+
def initialize(name, type = nil, description = nil, described_by = nil, settings = {})
|
138
|
+
@name = name
|
139
|
+
@type = type
|
140
|
+
@description = description
|
141
|
+
@described_by = described_by
|
142
|
+
@settings = settings
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|