openapi_parser 0.1.5 → 0.1.6
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/.rubocop.yml +5 -2
- data/.rubocop_ignore.yml +6 -0
- data/.travis.yml +33 -4
- data/CHANGELOG.md +9 -0
- data/README.md +39 -6
- data/lib/openapi_parser/concern.rb +2 -1
- data/lib/openapi_parser/concerns/expandable.rb +52 -44
- data/lib/openapi_parser/concerns/media_type_selectable.rb +26 -0
- data/lib/openapi_parser/concerns/parser.rb +43 -0
- data/lib/openapi_parser/concerns/parser/core.rb +21 -0
- data/lib/openapi_parser/concerns/parser/hash.rb +10 -0
- data/lib/openapi_parser/concerns/parser/hash_body.rb +12 -0
- data/lib/openapi_parser/concerns/parser/list.rb +10 -0
- data/lib/openapi_parser/concerns/parser/object.rb +14 -0
- data/lib/openapi_parser/concerns/parser/value.rb +14 -0
- data/lib/openapi_parser/concerns/schema_loader.rb +58 -0
- data/lib/openapi_parser/concerns/schema_loader/base.rb +28 -0
- data/lib/openapi_parser/concerns/schema_loader/creator.rb +48 -0
- data/lib/openapi_parser/concerns/schema_loader/hash_body_loader.rb +37 -0
- data/lib/openapi_parser/concerns/schema_loader/hash_objects_loader.rb +29 -0
- data/lib/openapi_parser/concerns/schema_loader/list_loader.rb +28 -0
- data/lib/openapi_parser/concerns/schema_loader/objects_loader.rb +21 -0
- data/lib/openapi_parser/concerns/schema_loader/values_loader.rb +10 -0
- data/lib/openapi_parser/config.rb +1 -1
- data/lib/openapi_parser/errors.rb +9 -0
- data/lib/openapi_parser/path_item_finder.rb +18 -18
- data/lib/openapi_parser/request_operation.rb +4 -4
- data/lib/openapi_parser/schema_validator.rb +77 -54
- data/lib/openapi_parser/schema_validators/all_of_validator.rb +16 -0
- data/lib/openapi_parser/schema_validators/any_of_validator.rb +1 -1
- data/lib/openapi_parser/schema_validators/array_validator.rb +2 -4
- data/lib/openapi_parser/schema_validators/base.rb +9 -6
- data/lib/openapi_parser/schema_validators/boolean_validator.rb +11 -9
- data/lib/openapi_parser/schema_validators/float_validator.rb +8 -10
- data/lib/openapi_parser/schema_validators/integer_validator.rb +11 -10
- data/lib/openapi_parser/schema_validators/nil_validator.rb +1 -0
- data/lib/openapi_parser/schema_validators/object_validator.rb +3 -3
- data/lib/openapi_parser/schema_validators/string_validator.rb +13 -13
- data/lib/openapi_parser/schemas/base.rb +1 -2
- data/lib/openapi_parser/schemas/media_type.rb +3 -1
- data/lib/openapi_parser/schemas/openapi.rb +1 -1
- data/lib/openapi_parser/schemas/operation.rb +17 -14
- data/lib/openapi_parser/schemas/parameter.rb +2 -2
- data/lib/openapi_parser/schemas/request_body.rb +12 -5
- data/lib/openapi_parser/schemas/response.rb +4 -4
- data/lib/openapi_parser/schemas/responses.rb +21 -3
- data/lib/openapi_parser/version.rb +1 -1
- data/openapi_parser.gemspec +3 -2
- metadata +51 -19
- data/lib/openapi_parser/concerns/parseable.rb +0 -238
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0035d4ece30f151226f04a1462ae6cf4d54c36011b315810bd49588f66b0632
|
4
|
+
data.tar.gz: cae26e5b18e0ab71b2027d56a828cccd737126852b96c68facf88f8ba27db0ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0456ee6d9363ff05c1ef517cbc9aa8cfbcad55aa054e012009ec685a5b97c7779c897842918a868dae3acefa143bbfa7790fc7bb1ba370e04293fc7ead130ef4
|
7
|
+
data.tar.gz: d2855d0574bfdc5a769576ffa89af5d1006f960af4a4790e92edfbe5763eb3a954698f71522d599524b1b9d906f11632440167c4e37e524435804873aeede533
|
data/.rubocop.yml
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
inherit_gem:
|
2
2
|
fincop:
|
3
|
-
- 'config/rails.yml'
|
3
|
+
# - 'config/rails.yml'
|
4
4
|
- 'config/rspec.yml'
|
5
5
|
- 'config/rubocop.yml'
|
6
|
-
|
6
|
+
# If you are using Rails 4, activate this cop.
|
7
7
|
# - 'config/disabled_for_rails_4.yml'
|
8
8
|
|
9
|
+
inherit_from:
|
10
|
+
- '.rubocop_ignore.yml'
|
11
|
+
|
9
12
|
AllCops:
|
10
13
|
TargetRubyVersion: 2.5
|
data/.rubocop_ignore.yml
ADDED
data/.travis.yml
CHANGED
@@ -1,7 +1,36 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
env:
|
2
|
+
global:
|
3
|
+
- CC_TEST_REPORTER_ID=b49a1717b8ff0aef9eced41d0f87d350a88b46d55083ba2e3df8b6f441ae3fb7
|
4
|
+
|
3
5
|
language: ruby
|
4
|
-
|
6
|
+
|
5
7
|
rvm:
|
8
|
+
- 2.3.8
|
9
|
+
- 2.4.5
|
6
10
|
- 2.5.3
|
7
|
-
|
11
|
+
- 2.6.0
|
12
|
+
- ruby-head
|
13
|
+
|
14
|
+
cache: bundler
|
15
|
+
|
16
|
+
before_script:
|
17
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
18
|
+
- chmod +x ./cc-test-reporter
|
19
|
+
- ./cc-test-reporter before-build
|
20
|
+
|
21
|
+
script: bundle exec rspec
|
22
|
+
|
23
|
+
after_script:
|
24
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
25
|
+
|
26
|
+
notifications:
|
27
|
+
email: false
|
28
|
+
|
29
|
+
sudo: false
|
30
|
+
|
31
|
+
git:
|
32
|
+
depth: 10
|
33
|
+
|
34
|
+
matrix:
|
35
|
+
allow_failures:
|
36
|
+
- rvm: ruby-head
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,8 +1,41 @@
|
|
1
1
|
# OpenAPI Parser
|
2
|
+
[](https://travis-ci.org/ota42y/openapi_parser)
|
3
|
+
[](https://badge.fury.io/rb/openapi_parser)
|
4
|
+
[](https://www.rubydoc.info/gems/openapi_parser)
|
5
|
+
[](https://codeclimate.com/github/ota42y/openapi_parser/maintainability)
|
6
|
+
[](https://codeclimate.com/github/ota42y/openapi_parser/test_coverage)
|
7
|
+
[](https://inch-ci.org/github/ota42y/openapi_parser)
|
2
8
|
|
3
|
-
|
9
|
+
This is OpenAPI3 parser and validator.
|
4
10
|
|
5
|
-
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
root = OpenAPIParser.parse(YAML.load_file('open_api_3/schema.yml'))
|
15
|
+
|
16
|
+
# request operation combine path parameters and OpenAPI3's Operation Object
|
17
|
+
request_operation = root.request_operation(:post, '/validate')
|
18
|
+
|
19
|
+
ret = request_operation.validate_request_body('application/json', {"integer" => 1})
|
20
|
+
# => {"integer" => 1}
|
21
|
+
|
22
|
+
# invalid parameter
|
23
|
+
request_operation.validate_request_body('application/json', {"integer" => '1'})
|
24
|
+
# => OpenAPIParser::ValidateError: 1 class is String but it's not valid integer in #/paths/~1validate/post/requestBody/content/application~1json/schema/properties/integer
|
25
|
+
|
26
|
+
# path parameter
|
27
|
+
request_operation = root.request_operation(:get, '/path_template_test/1')
|
28
|
+
request_operation.path_params
|
29
|
+
# => {"template_name"=>"1"}
|
30
|
+
|
31
|
+
# coerce parameter
|
32
|
+
root = OpenAPIParser.parse(YAML.load_file('open_api_3/schema.yml'), {coerce_value: true, datetime_coerce_class: DateTime})
|
33
|
+
request_operation = root.request_operation(:get, '/string_params_coercer')
|
34
|
+
request_operation.validate_request_parameter({'integer_1' => '1', 'datetime_string' => '2016-04-01T16:00:00+09:00'})
|
35
|
+
# => {"integer_1"=>1, "datetime_string"=>#<DateTime: 2016-04-01T16:00:00+09:00 ((2457480j,25200s,0n),+32400s,2299161j)>
|
36
|
+
# convert number string to Integer and datetime string to DateTime class
|
37
|
+
|
38
|
+
```
|
6
39
|
|
7
40
|
## Installation
|
8
41
|
|
@@ -20,9 +53,9 @@ Or install it yourself as:
|
|
20
53
|
|
21
54
|
$ gem install openapi_parser
|
22
55
|
|
23
|
-
##
|
24
|
-
|
25
|
-
|
56
|
+
## ToDo
|
57
|
+
- correct schema checker
|
58
|
+
- more detailed validator
|
26
59
|
|
27
60
|
## Development
|
28
61
|
|
@@ -32,7 +65,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
65
|
|
33
66
|
## Contributing
|
34
67
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
68
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ota42y/openapi_parser. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
36
69
|
|
37
70
|
## License
|
38
71
|
|
@@ -1,25 +1,30 @@
|
|
1
1
|
module OpenAPIParser::Expandable
|
2
|
+
# expand refs
|
3
|
+
# @param [OpenAPIParser::Schemas::Base] root
|
4
|
+
# @return nil
|
2
5
|
def expand_reference(root)
|
3
|
-
expand_list_objects(root, self.class._openapi_attr_list_objects
|
4
|
-
expand_objects(root, self.class._openapi_attr_objects
|
5
|
-
expand_hash_objects(root, self.class._openapi_attr_hash_objects
|
6
|
-
expand_hash_objects(root, self.class._openapi_attr_hash_body_objects
|
6
|
+
expand_list_objects(root, self.class._openapi_attr_list_objects.keys)
|
7
|
+
expand_objects(root, self.class._openapi_attr_objects.keys)
|
8
|
+
expand_hash_objects(root, self.class._openapi_attr_hash_objects.keys)
|
9
|
+
expand_hash_objects(root, self.class._openapi_attr_hash_body_objects.keys)
|
10
|
+
nil
|
7
11
|
end
|
8
12
|
|
9
13
|
private
|
10
14
|
|
11
|
-
|
12
|
-
|
15
|
+
def expand_hash_objects(root, attribute_names)
|
16
|
+
return unless attribute_names
|
13
17
|
|
14
|
-
|
18
|
+
attribute_names.each { |name| expand_hash_attribute(root, name) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def expand_hash_attribute(root, name)
|
15
22
|
h = send(name)
|
16
|
-
|
23
|
+
return if h.nil?
|
17
24
|
|
18
25
|
update_values = h.map do |k, v|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
nil
|
26
|
+
new_object = expand_object(root, v)
|
27
|
+
new_object.nil? ? nil : [k, new_object]
|
23
28
|
end
|
24
29
|
|
25
30
|
update_values.compact.each do |k, v|
|
@@ -27,50 +32,53 @@ module OpenAPIParser::Expandable
|
|
27
32
|
h[k] = v
|
28
33
|
end
|
29
34
|
end
|
30
|
-
end
|
31
35
|
|
32
|
-
|
33
|
-
|
36
|
+
def expand_objects(root, attribute_names)
|
37
|
+
return unless attribute_names
|
34
38
|
|
35
|
-
|
36
|
-
|
37
|
-
|
39
|
+
attribute_names.each do |name|
|
40
|
+
v = send(name)
|
41
|
+
next if v.nil?
|
38
42
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
v.expand_reference(root)
|
43
|
+
new_object = expand_object(root, v)
|
44
|
+
next if new_object.nil?
|
45
|
+
|
46
|
+
_update_child_object(v, new_object)
|
47
|
+
self.instance_variable_set("@#{name}", new_object)
|
45
48
|
end
|
46
49
|
end
|
47
|
-
end
|
48
50
|
|
49
|
-
|
50
|
-
|
51
|
+
def expand_list_objects(root, attribute_names)
|
52
|
+
return unless attribute_names
|
53
|
+
|
54
|
+
attribute_names.each do |name|
|
55
|
+
l = send(name)
|
56
|
+
next if l.nil?
|
51
57
|
|
52
|
-
|
53
|
-
|
54
|
-
|
58
|
+
l.each_with_index do |v, idx|
|
59
|
+
new_object = expand_object(root, v)
|
60
|
+
next if new_object.nil?
|
55
61
|
|
56
|
-
|
57
|
-
|
58
|
-
obj = referenced_object(root, v)
|
59
|
-
_update_child_object(v, obj)
|
60
|
-
l[idx] = obj
|
61
|
-
elsif v.is_a?(OpenAPIParser::Expandable)
|
62
|
-
v.expand_reference(root)
|
62
|
+
_update_child_object(v, new_object)
|
63
|
+
l[idx] = new_object
|
63
64
|
end
|
64
65
|
end
|
65
66
|
end
|
66
|
-
end
|
67
67
|
|
68
|
+
def expand_object(root, object)
|
69
|
+
if object.kind_of?(OpenAPIParser::Schemas::Reference)
|
70
|
+
return referenced_object(root, object)
|
71
|
+
end
|
72
|
+
|
73
|
+
object.expand_reference(root) if object.kind_of?(OpenAPIParser::Expandable)
|
74
|
+
nil
|
75
|
+
end
|
68
76
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
77
|
+
# @param [OpenAPIParser::Schemas::OpenAPI] root
|
78
|
+
# @param [OpenAPIParser::Schemas::Reference] reference
|
79
|
+
def referenced_object(root, reference)
|
80
|
+
obj = root.find_object(reference.ref)
|
73
81
|
|
74
|
-
|
75
|
-
|
82
|
+
obj.kind_of?(OpenAPIParser::Schemas::Reference) ? referenced_object(root, obj) : obj
|
83
|
+
end
|
76
84
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module OpenAPIParser::MediaTypeSelectable
|
2
|
+
# select media type by content_type (consider wild card definition)
|
3
|
+
# @param [String] content_type
|
4
|
+
# @param [Hash{String => OpenAPIParser::Schemas::MediaType}] content
|
5
|
+
# @return [OpenAPIParser::Schemas::MediaType, nil]
|
6
|
+
def select_media_type(content_type, content)
|
7
|
+
return nil unless content_type
|
8
|
+
|
9
|
+
if (media_type = content[content_type])
|
10
|
+
return media_type
|
11
|
+
end
|
12
|
+
|
13
|
+
# application/json => [application, json]
|
14
|
+
splited = content_type.split('/')
|
15
|
+
|
16
|
+
if (media_type = content["#{splited.first}/*"])
|
17
|
+
return media_type
|
18
|
+
end
|
19
|
+
|
20
|
+
if (media_type = content['*/*'])
|
21
|
+
return media_type
|
22
|
+
end
|
23
|
+
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module OpenAPIParser::Parser
|
2
|
+
end
|
3
|
+
|
4
|
+
require_relative './parser/core'
|
5
|
+
require_relative './schema_loader'
|
6
|
+
|
7
|
+
module OpenAPIParser::Parser
|
8
|
+
def self.included(base)
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
end
|
11
|
+
module ClassMethods
|
12
|
+
extend Forwardable
|
13
|
+
|
14
|
+
def_delegators :_parser_core, :_openapi_attr_values, :openapi_attr_value, :openapi_attr_values
|
15
|
+
def_delegators :_parser_core, :_openapi_attr_objects, :openapi_attr_objects, :openapi_attr_object
|
16
|
+
def_delegators :_parser_core, :_openapi_attr_list_objects, :openapi_attr_list_object
|
17
|
+
def_delegators :_parser_core, :_openapi_attr_hash_objects, :openapi_attr_hash_object
|
18
|
+
def_delegators :_parser_core, :_openapi_attr_hash_body_objects, :openapi_attr_hash_body_objects
|
19
|
+
|
20
|
+
def _parser_core
|
21
|
+
@_parser_core ||= OpenAPIParser::Parser::Core.new(self)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [OpenAPIParser::Schemas::Base] old
|
26
|
+
# @param [OpenAPIParser::Schemas::Base] new
|
27
|
+
def _update_child_object(old, new)
|
28
|
+
_openapi_all_child_objects[old.object_reference] = new
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Hash{String => OpenAPIParser::Schemas::Base}]
|
32
|
+
def _openapi_all_child_objects
|
33
|
+
@_openapi_all_child_objects ||= {}
|
34
|
+
end
|
35
|
+
|
36
|
+
# load data by schema definition in core and set children to _openapi_all_child_objects
|
37
|
+
# @return nil
|
38
|
+
def load_data
|
39
|
+
loader = ::OpenAPIParser::SchemaLoader.new(self, self.class._parser_core)
|
40
|
+
@_openapi_all_child_objects = loader.load_data
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative './value'
|
2
|
+
require_relative './object'
|
3
|
+
require_relative './list'
|
4
|
+
require_relative './hash'
|
5
|
+
require_relative './hash_body'
|
6
|
+
|
7
|
+
class OpenAPIParser::Parser::Core
|
8
|
+
include OpenAPIParser::Parser::Value
|
9
|
+
include OpenAPIParser::Parser::Object
|
10
|
+
include OpenAPIParser::Parser::List
|
11
|
+
include OpenAPIParser::Parser::Hash
|
12
|
+
include OpenAPIParser::Parser::HashBody
|
13
|
+
|
14
|
+
def initialize(target_klass)
|
15
|
+
@target_klass = target_klass
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :target_klass
|
21
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module OpenAPIParser::Parser::Hash
|
2
|
+
def _openapi_attr_hash_objects
|
3
|
+
@_openapi_attr_hash_objects ||= {}
|
4
|
+
end
|
5
|
+
|
6
|
+
def openapi_attr_hash_object(name, klass, options = {})
|
7
|
+
target_klass.send(:attr_reader, name)
|
8
|
+
_openapi_attr_hash_objects[name] = ::OpenAPIParser::SchemaLoader::HashObjectsLoader.new(name, options.merge(klass: klass))
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module OpenAPIParser::Parser::HashBody
|
2
|
+
def _openapi_attr_hash_body_objects
|
3
|
+
@_openapi_attr_hash_body_objects ||= {}
|
4
|
+
end
|
5
|
+
|
6
|
+
def openapi_attr_hash_body_objects(name, klass, options = {})
|
7
|
+
#options[:reject_keys] = options[:reject_keys] ? options[:reject_keys].map(&:to_s) : []
|
8
|
+
|
9
|
+
target_klass.send(:attr_reader, name)
|
10
|
+
_openapi_attr_hash_body_objects[name] = ::OpenAPIParser::SchemaLoader::HashBodyLoader.new(name, options.merge(klass: klass))
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module OpenAPIParser::Parser::List
|
2
|
+
def _openapi_attr_list_objects
|
3
|
+
@_openapi_attr_list_objects ||= {}
|
4
|
+
end
|
5
|
+
|
6
|
+
def openapi_attr_list_object(name, klass, options = {})
|
7
|
+
target_klass.send(:attr_reader, name)
|
8
|
+
_openapi_attr_list_objects[name] = OpenAPIParser::SchemaLoader::ListLoader.new(name, options.merge(klass: klass))
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module OpenAPIParser::Parser::Object
|
2
|
+
def _openapi_attr_objects
|
3
|
+
@_openapi_attr_objects ||= {}
|
4
|
+
end
|
5
|
+
|
6
|
+
def openapi_attr_objects(*names, klass)
|
7
|
+
names.each { |name| openapi_attr_object(name, klass) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def openapi_attr_object(name, klass, options = {})
|
11
|
+
target_klass.send(:attr_reader, name)
|
12
|
+
_openapi_attr_objects[name] = OpenAPIParser::SchemaLoader::ObjectsLoader.new(name, options.merge(klass: klass))
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module OpenAPIParser::Parser::Value
|
2
|
+
def _openapi_attr_values
|
3
|
+
@_openapi_attr_values ||= {}
|
4
|
+
end
|
5
|
+
|
6
|
+
def openapi_attr_values(*names)
|
7
|
+
names.each { |name| openapi_attr_value(name) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def openapi_attr_value(name, options = {})
|
11
|
+
target_klass.send(:attr_reader, name)
|
12
|
+
_openapi_attr_values[name] = OpenAPIParser::SchemaLoader::ValuesLoader.new(name, options)
|
13
|
+
end
|
14
|
+
end
|