openapi_parser 0.9.0 → 0.10.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/CHANGELOG.md +4 -0
- data/lib/openapi_parser.rb +62 -4
- data/lib/openapi_parser/concerns/findable.rb +14 -1
- data/lib/openapi_parser/errors.rb +11 -0
- data/lib/openapi_parser/schema_validators/string_validator.rb +11 -0
- data/lib/openapi_parser/schemas/openapi.rb +28 -1
- data/lib/openapi_parser/schemas/paths.rb +1 -1
- data/lib/openapi_parser/version.rb +1 -1
- data/openapi_parser.gemspec +2 -2
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98afa3c7fb754859a594373659d18ebb81483581c948621d0ea050c360da38ec
|
4
|
+
data.tar.gz: 9cf7b695875b6ca55a89a3d5e1a288381d39e203c5fbb469beeb7465232ff0a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddc32d47e0072b78f4790a6b6fa031eab103bb4665d5c0cfe4e7ac2ac9b2e04a048a82f4ddefd40fd112221e389cd86568ac67c3ca9db6f46ae4b9f8ece23c8a
|
7
|
+
data.tar.gz: bdd2fdeaec224eaecdde6088abc7eb69513a4ab9e2afffbf23a6a21f9e13a640bddaf6bd7fbbaab16dff588c021bc12296aefd01b1efcb28908f33f8b263f9ad
|
data/CHANGELOG.md
CHANGED
data/lib/openapi_parser.rb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
+
require 'uri'
|
1
2
|
require 'time'
|
3
|
+
require 'json'
|
4
|
+
require 'psych'
|
5
|
+
require 'pathname'
|
6
|
+
require 'open-uri'
|
2
7
|
|
3
8
|
require 'openapi_parser/version'
|
4
9
|
require 'openapi_parser/config'
|
@@ -13,14 +18,67 @@ require 'openapi_parser/reference_expander'
|
|
13
18
|
|
14
19
|
module OpenAPIParser
|
15
20
|
class << self
|
21
|
+
# Load schema yaml object. Uri is not set for returned schema.
|
16
22
|
# @return [OpenAPIParser::Schemas::OpenAPI]
|
17
23
|
def parse(schema, config = {})
|
18
|
-
|
19
|
-
|
24
|
+
load_hash(schema, config: Config.new(config), uri: nil, schema_registry: {})
|
25
|
+
end
|
26
|
+
|
27
|
+
# Load schema in specified filepath. If file path is relative, it is resolved using working directory.
|
28
|
+
# @return [OpenAPIParser::Schemas::OpenAPI]
|
29
|
+
def load(filepath, config = {})
|
30
|
+
path = Pathname.new(filepath)
|
31
|
+
path = Pathname.getwd + path if path.relative?
|
32
|
+
load_uri(URI.join("file:///", path.to_s), config: Config.new(config), schema_registry: {})
|
33
|
+
end
|
20
34
|
|
21
|
-
|
35
|
+
# Load schema located by the passed uri. Uri must be absolute.
|
36
|
+
# @return [OpenAPIParser::Schemas::OpenAPI]
|
37
|
+
def load_uri(uri, config:, schema_registry:)
|
38
|
+
# Open-uri doesn't open file scheme uri, so we try to open file path directly
|
39
|
+
# File scheme uri which points to a remote file is not supported.
|
40
|
+
content = if uri.scheme == 'file'
|
41
|
+
open(uri.path, &:read)
|
42
|
+
else
|
43
|
+
uri.open(&:read)
|
44
|
+
end
|
22
45
|
|
23
|
-
|
46
|
+
extension = Pathname.new(uri.path).extname
|
47
|
+
load_hash(parse_file(content, extension), config: config, uri: uri, schema_registry: schema_registry)
|
24
48
|
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def parse_file(content, extension)
|
53
|
+
case extension.downcase
|
54
|
+
when '.yaml', '.yml'
|
55
|
+
parse_yaml(content)
|
56
|
+
when '.json'
|
57
|
+
parse_json(content)
|
58
|
+
else
|
59
|
+
# When extension is something we don't know, try to parse as json first. If it fails, parse as yaml
|
60
|
+
begin
|
61
|
+
parse_json(content)
|
62
|
+
rescue JSON::ParserError
|
63
|
+
parse_yaml(content)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse_yaml(content)
|
69
|
+
Psych.safe_load(content)
|
70
|
+
end
|
71
|
+
|
72
|
+
def parse_json(content)
|
73
|
+
JSON.parse(content)
|
74
|
+
end
|
75
|
+
|
76
|
+
def load_hash(hash, config:, uri:, schema_registry:)
|
77
|
+
root = Schemas::OpenAPI.new(hash, config, uri: uri, schema_registry: schema_registry)
|
78
|
+
|
79
|
+
OpenAPIParser::ReferenceExpander.expand(root) if config.expand_reference
|
80
|
+
|
81
|
+
root
|
82
|
+
end
|
25
83
|
end
|
26
84
|
end
|
@@ -1,9 +1,13 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
1
3
|
module OpenAPIParser::Findable
|
2
4
|
# @param [String] reference
|
3
5
|
# @return [OpenAPIParser::Findable]
|
4
6
|
def find_object(reference)
|
5
|
-
return nil unless reference.start_with?(object_reference)
|
6
7
|
return self if object_reference == reference
|
8
|
+
remote_reference = !reference.start_with?('#')
|
9
|
+
return find_remote_object(reference) if remote_reference
|
10
|
+
return nil unless reference.start_with?(object_reference)
|
7
11
|
|
8
12
|
@find_object_cache = {} unless defined? @find_object_cache
|
9
13
|
if (obj = @find_object_cache[reference])
|
@@ -30,4 +34,13 @@ module OpenAPIParser::Findable
|
|
30
34
|
|
31
35
|
_openapi_all_child_objects.values.each(&:purge_object_cache)
|
32
36
|
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def find_remote_object(reference)
|
41
|
+
reference_uri = URI(reference)
|
42
|
+
fragment = reference_uri.fragment
|
43
|
+
reference_uri.fragment = nil
|
44
|
+
root.load_another_schema(reference_uri)&.find_object("##{fragment}")
|
45
|
+
end
|
33
46
|
end
|
@@ -178,6 +178,17 @@ module OpenAPIParser
|
|
178
178
|
end
|
179
179
|
end
|
180
180
|
|
181
|
+
class InvalidUUIDFormat < OpenAPIError
|
182
|
+
def initialize(value, reference)
|
183
|
+
super(reference)
|
184
|
+
@value = value
|
185
|
+
end
|
186
|
+
|
187
|
+
def message
|
188
|
+
"#{@reference} Value: #{@value} is not conformant with UUID format"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
181
192
|
class NotExistStatusCodeDefinition < OpenAPIError
|
182
193
|
def message
|
183
194
|
"#{@reference} status code definition does not exist"
|
@@ -27,6 +27,9 @@ class OpenAPIParser::SchemaValidator
|
|
27
27
|
value, err = validate_email_format(value, schema)
|
28
28
|
return [nil, err] if err
|
29
29
|
|
30
|
+
value, err = validate_uuid_format(value, schema)
|
31
|
+
return [nil, err] if err
|
32
|
+
|
30
33
|
[value, nil]
|
31
34
|
end
|
32
35
|
|
@@ -75,5 +78,13 @@ class OpenAPIParser::SchemaValidator
|
|
75
78
|
|
76
79
|
return [nil, OpenAPIParser::InvalidEmailFormat.new(value, schema.object_reference)]
|
77
80
|
end
|
81
|
+
|
82
|
+
def validate_uuid_format(value, schema)
|
83
|
+
return [value, nil] unless schema.format == 'uuid'
|
84
|
+
|
85
|
+
return [value, nil] if value.match(/[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}/)
|
86
|
+
|
87
|
+
return [nil, OpenAPIParser::InvalidUUIDFormat.new(value, schema.object_reference)]
|
88
|
+
end
|
78
89
|
end
|
79
90
|
end
|
@@ -5,11 +5,16 @@
|
|
5
5
|
|
6
6
|
module OpenAPIParser::Schemas
|
7
7
|
class OpenAPI < Base
|
8
|
-
def initialize(raw_schema, config)
|
8
|
+
def initialize(raw_schema, config, uri: nil, schema_registry: {})
|
9
9
|
super('#', nil, self, raw_schema)
|
10
10
|
@find_object_cache = {}
|
11
11
|
@path_item_finder = OpenAPIParser::PathItemFinder.new(paths) if paths # invalid definition
|
12
12
|
@config = config
|
13
|
+
@uri = uri
|
14
|
+
@schema_registry = schema_registry
|
15
|
+
|
16
|
+
# schema_registery is shared among schemas, and prevents a schema from being loaded multiple times
|
17
|
+
schema_registry[uri] = self if uri
|
13
18
|
end
|
14
19
|
|
15
20
|
# @!attribute [r] openapi
|
@@ -28,5 +33,27 @@ module OpenAPIParser::Schemas
|
|
28
33
|
def request_operation(http_method, request_path)
|
29
34
|
OpenAPIParser::RequestOperation.create(http_method, request_path, @path_item_finder, @config)
|
30
35
|
end
|
36
|
+
|
37
|
+
# load another schema with shared config and schema_registry
|
38
|
+
# @return [OpenAPIParser::Schemas::OpenAPI]
|
39
|
+
def load_another_schema(uri)
|
40
|
+
resolved_uri = resolve_uri(uri)
|
41
|
+
return if resolved_uri.nil?
|
42
|
+
|
43
|
+
loaded = @schema_registry[resolved_uri]
|
44
|
+
return loaded if loaded
|
45
|
+
|
46
|
+
OpenAPIParser.load_uri(resolved_uri, config: @config, schema_registry: @schema_registry)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def resolve_uri(uri)
|
52
|
+
if uri.absolute?
|
53
|
+
uri
|
54
|
+
else
|
55
|
+
@uri&.merge(uri)
|
56
|
+
end
|
57
|
+
end
|
31
58
|
end
|
32
59
|
end
|
@@ -2,6 +2,6 @@ module OpenAPIParser::Schemas
|
|
2
2
|
class Paths < Base
|
3
3
|
# @!attribute [r] path
|
4
4
|
# @return [Hash{String => PathItem, Reference}, nil]
|
5
|
-
openapi_attr_hash_body_objects 'path', PathItem, reference:
|
5
|
+
openapi_attr_hash_body_objects 'path', PathItem, reference: true, allow_data_type: false
|
6
6
|
end
|
7
7
|
end
|
data/openapi_parser.gemspec
CHANGED
@@ -24,9 +24,9 @@ Gem::Specification.new do |spec|
|
|
24
24
|
|
25
25
|
spec.add_development_dependency 'bundler', '>= 1.16'
|
26
26
|
spec.add_development_dependency 'fincop'
|
27
|
-
spec.add_development_dependency 'pry'
|
27
|
+
spec.add_development_dependency 'pry', '~> 0.12.0'
|
28
28
|
spec.add_development_dependency 'pry-byebug'
|
29
|
-
spec.add_development_dependency 'rake', '
|
29
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
30
30
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
31
31
|
spec.add_development_dependency 'rspec-parameterized'
|
32
32
|
spec.add_development_dependency 'simplecov'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openapi_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ota42y
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -42,16 +42,16 @@ dependencies:
|
|
42
42
|
name: pry
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.12.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.12.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: pry-byebug
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,16 +70,16 @@ dependencies:
|
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 12.3.3
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 12.3.3
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rspec
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -222,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
222
|
- !ruby/object:Gem::Version
|
223
223
|
version: '0'
|
224
224
|
requirements: []
|
225
|
-
rubygems_version: 3.
|
225
|
+
rubygems_version: 3.0.3
|
226
226
|
signing_key:
|
227
227
|
specification_version: 4
|
228
228
|
summary: OpenAPI3 parser
|