openapi_parser 0.11.1 → 0.14.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/.github/workflows/ci.yaml +17 -0
- data/.gitignore +4 -1
- data/CHANGELOG.md +25 -0
- data/README.md +1 -3
- data/lib/openapi_parser.rb +4 -1
- data/lib/openapi_parser/concerns/findable.rb +8 -5
- data/lib/openapi_parser/errors.rb +27 -16
- data/lib/openapi_parser/path_item_finder.rb +42 -7
- data/lib/openapi_parser/schema_validator.rb +6 -1
- data/lib/openapi_parser/schema_validators/all_of_validator.rb +7 -2
- data/lib/openapi_parser/schema_validators/base.rb +6 -2
- data/lib/openapi_parser/schema_validators/boolean_validator.rb +5 -0
- data/lib/openapi_parser/schema_validators/float_validator.rb +3 -3
- data/lib/openapi_parser/schema_validators/integer_validator.rb +3 -5
- data/lib/openapi_parser/schema_validators/object_validator.rb +11 -1
- data/lib/openapi_parser/schema_validators/string_validator.rb +15 -0
- data/lib/openapi_parser/schema_validators/unspecified_type_validator.rb +8 -0
- data/lib/openapi_parser/version.rb +1 -1
- metadata +8 -7
- data/.travis.yml +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1b06e3e4d6ad28828a02c2a4a79140439b9119ac53b73494318386195cc6275
|
4
|
+
data.tar.gz: 4360946a10aa364d8c0de18d773eee3df2ee683373de2178307f52530806e81a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be2a98609d41e4207edff4aaa61687b34dc568cb36e38b37eef42c7edffc836ffb9110465dda772c41025bc0fce125115da370e36949414ceb8902051c81b7b8
|
7
|
+
data.tar.gz: 3047ab4d4ef9f465e9c9373567c11e323ecd135d994002d8578426bdc38d5cdbe5922050d66bdf701551fb10fcb3206029276b49a33e2bc1d755278cb105a9e3
|
@@ -0,0 +1,17 @@
|
|
1
|
+
name: ci
|
2
|
+
on: [push]
|
3
|
+
jobs:
|
4
|
+
test:
|
5
|
+
strategy:
|
6
|
+
fail-fast: false
|
7
|
+
matrix:
|
8
|
+
os: [ubuntu-latest, macos-latest]
|
9
|
+
ruby: [2.4, 2.5, 2.6, 2.7, '3.0', head]
|
10
|
+
runs-on: ${{ matrix.os }}
|
11
|
+
steps:
|
12
|
+
- uses: actions/checkout@v2
|
13
|
+
- uses: ruby/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
ruby-version: ${{ matrix.ruby }}
|
16
|
+
bundler-cache: true
|
17
|
+
- run: bundle exec rake
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
## Unreleased
|
2
2
|
|
3
|
+
## 0.14.0 (2021-05-24)
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Add basic polymorphism handling #103
|
7
|
+
* Support empty schema as any type #109
|
8
|
+
* Add date format validation for string #102
|
9
|
+
|
10
|
+
### Fixed
|
11
|
+
* Fix anyOf coercion to float and integer when value is a non-string type #110
|
12
|
+
|
13
|
+
## 0.13.0 (2021-05-01)
|
14
|
+
* Fix a problem with remote reference to path items which have path parameters #95
|
15
|
+
* Support enum for booleans. #104
|
16
|
+
|
17
|
+
## 0.12.1 (2020-08-27)
|
18
|
+
* Use CGI.unescape (warning fix) #92
|
19
|
+
|
20
|
+
## 0.12.0 (2020-08-26)
|
21
|
+
* Find path by extracted params than path length #84
|
22
|
+
* Unescape ref URI before lookup in OpenAPIParser::Findable #85
|
23
|
+
* Improved path parameter matching code to allow file extensions, multiple parameters inside one path element, etc #90
|
24
|
+
|
25
|
+
## 0.11.2 (2020-05-23)
|
26
|
+
* Allow date and time content in YAML #81
|
27
|
+
|
3
28
|
## 0.11.1 (2020-05-09)
|
4
29
|
* fix too many warning
|
5
30
|
|
data/README.md
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
# OpenAPI Parser
|
2
|
-
[](https://github.com/ota42y/openapi_parser/actions/workflows/ci.yaml)
|
3
3
|
[](https://badge.fury.io/rb/openapi_parser)
|
4
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
5
|
[](https://inch-ci.org/github/ota42y/openapi_parser)
|
8
6
|
|
9
7
|
This is OpenAPI3 parser and validator.
|
data/lib/openapi_parser.rb
CHANGED
@@ -78,7 +78,10 @@ module OpenAPIParser
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def parse_yaml(content)
|
81
|
-
|
81
|
+
# FIXME: when drop ruby 2.5, we should use permitted_classes
|
82
|
+
(Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.6.0")) ?
|
83
|
+
Psych.safe_load(content, [Date, Time]) :
|
84
|
+
Psych.safe_load(content, permitted_classes: [Date, Time])
|
82
85
|
end
|
83
86
|
|
84
87
|
def parse_json(content)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'cgi'
|
1
2
|
require 'uri'
|
2
3
|
|
3
4
|
module OpenAPIParser::Findable
|
@@ -9,19 +10,21 @@ module OpenAPIParser::Findable
|
|
9
10
|
return find_remote_object(reference) if remote_reference
|
10
11
|
return nil unless reference.start_with?(object_reference)
|
11
12
|
|
13
|
+
unescaped_reference = CGI.unescape(reference)
|
14
|
+
|
12
15
|
@find_object_cache = {} unless defined? @find_object_cache
|
13
|
-
if (obj = @find_object_cache[
|
16
|
+
if (obj = @find_object_cache[unescaped_reference])
|
14
17
|
return obj
|
15
18
|
end
|
16
19
|
|
17
|
-
if (child = _openapi_all_child_objects[
|
18
|
-
@find_object_cache[
|
20
|
+
if (child = _openapi_all_child_objects[unescaped_reference])
|
21
|
+
@find_object_cache[unescaped_reference] = child
|
19
22
|
return child
|
20
23
|
end
|
21
24
|
|
22
25
|
_openapi_all_child_objects.values.each do |c|
|
23
|
-
if (obj = c.find_object(
|
24
|
-
@find_object_cache[
|
26
|
+
if (obj = c.find_object(unescaped_reference))
|
27
|
+
@find_object_cache[unescaped_reference] = obj
|
25
28
|
return obj
|
26
29
|
end
|
27
30
|
end
|
@@ -13,7 +13,7 @@ module OpenAPIParser
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def message
|
16
|
-
"#{@reference} expected #{@type}, but received #{@data.class}: #{@data}"
|
16
|
+
"#{@reference} expected #{@type}, but received #{@data.class}: #{@data.inspect}"
|
17
17
|
end
|
18
18
|
|
19
19
|
class << self
|
@@ -73,7 +73,7 @@ module OpenAPIParser
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def message
|
76
|
-
"discriminator propertyName #{@key} does not exist in value #{@value} in #{@reference}"
|
76
|
+
"discriminator propertyName #{@key} does not exist in value #{@value.inspect} in #{@reference}"
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -84,7 +84,7 @@ module OpenAPIParser
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def message
|
87
|
-
"#{@value} isn't one of in #{@reference}"
|
87
|
+
"#{@value.inspect} isn't one of in #{@reference}"
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
@@ -95,7 +95,7 @@ module OpenAPIParser
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def message
|
98
|
-
"#{@value} isn't any of in #{@reference}"
|
98
|
+
"#{@value.inspect} isn't any of in #{@reference}"
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
@@ -106,7 +106,7 @@ module OpenAPIParser
|
|
106
106
|
end
|
107
107
|
|
108
108
|
def message
|
109
|
-
"#{@value} isn't
|
109
|
+
"#{@value.inspect} isn't part of the enum in #{@reference}"
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
@@ -117,7 +117,7 @@ module OpenAPIParser
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def message
|
120
|
-
"#{@reference} #{@value} is less than minimum value"
|
120
|
+
"#{@reference} #{@value.inspect} is less than minimum value"
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
@@ -128,7 +128,7 @@ module OpenAPIParser
|
|
128
128
|
end
|
129
129
|
|
130
130
|
def message
|
131
|
-
"#{@reference} #{@value} cannot be less than or equal to exclusive minimum value"
|
131
|
+
"#{@reference} #{@value.inspect} cannot be less than or equal to exclusive minimum value"
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
@@ -139,7 +139,7 @@ module OpenAPIParser
|
|
139
139
|
end
|
140
140
|
|
141
141
|
def message
|
142
|
-
"#{@reference} #{@value} is more than maximum value"
|
142
|
+
"#{@reference} #{@value.inspect} is more than maximum value"
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
@@ -150,7 +150,7 @@ module OpenAPIParser
|
|
150
150
|
end
|
151
151
|
|
152
152
|
def message
|
153
|
-
"#{@reference} #{@value} cannot be more than or equal to exclusive maximum value"
|
153
|
+
"#{@reference} #{@value.inspect} cannot be more than or equal to exclusive maximum value"
|
154
154
|
end
|
155
155
|
end
|
156
156
|
|
@@ -163,7 +163,7 @@ module OpenAPIParser
|
|
163
163
|
end
|
164
164
|
|
165
165
|
def message
|
166
|
-
"#{@reference} pattern #{@pattern} does not match value: #{@value}#{@example ? ", example: #{@example}" : ""}"
|
166
|
+
"#{@reference} pattern #{@pattern} does not match value: #{@value.inspect}#{@example ? ", example: #{@example}" : ""}"
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
@@ -174,7 +174,7 @@ module OpenAPIParser
|
|
174
174
|
end
|
175
175
|
|
176
176
|
def message
|
177
|
-
"#{@reference} email address format does not match value: #{@value}"
|
177
|
+
"#{@reference} email address format does not match value: #{@value.inspect}"
|
178
178
|
end
|
179
179
|
end
|
180
180
|
|
@@ -185,7 +185,18 @@ module OpenAPIParser
|
|
185
185
|
end
|
186
186
|
|
187
187
|
def message
|
188
|
-
"#{@reference} Value: #{@value} is not conformant with UUID format"
|
188
|
+
"#{@reference} Value: #{@value.inspect} is not conformant with UUID format"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
class InvalidDateFormat < OpenAPIError
|
193
|
+
def initialize(value, reference)
|
194
|
+
super(reference)
|
195
|
+
@value = value
|
196
|
+
end
|
197
|
+
|
198
|
+
def message
|
199
|
+
"#{@reference} Value: #{@value.inspect} is not conformant with date format"
|
189
200
|
end
|
190
201
|
end
|
191
202
|
|
@@ -208,7 +219,7 @@ module OpenAPIParser
|
|
208
219
|
end
|
209
220
|
|
210
221
|
def message
|
211
|
-
"#{@reference} #{@value} is longer than max length"
|
222
|
+
"#{@reference} #{@value.inspect} is longer than max length"
|
212
223
|
end
|
213
224
|
end
|
214
225
|
|
@@ -219,7 +230,7 @@ module OpenAPIParser
|
|
219
230
|
end
|
220
231
|
|
221
232
|
def message
|
222
|
-
"#{@reference} #{@value} is shorter than min length"
|
233
|
+
"#{@reference} #{@value.inspect} is shorter than min length"
|
223
234
|
end
|
224
235
|
end
|
225
236
|
|
@@ -230,7 +241,7 @@ module OpenAPIParser
|
|
230
241
|
end
|
231
242
|
|
232
243
|
def message
|
233
|
-
"#{@reference} #{@value} contains more than max items"
|
244
|
+
"#{@reference} #{@value.inspect} contains more than max items"
|
234
245
|
end
|
235
246
|
end
|
236
247
|
|
@@ -241,7 +252,7 @@ module OpenAPIParser
|
|
241
252
|
end
|
242
253
|
|
243
254
|
def message
|
244
|
-
"#{@reference} #{@value} contains fewer than min items"
|
255
|
+
"#{@reference} #{@value.inspect} contains fewer than min items"
|
245
256
|
end
|
246
257
|
end
|
247
258
|
end
|
@@ -38,7 +38,41 @@ class OpenAPIParser::PathItemFinder
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
def parse_path_parameters(schema_path, request_path)
|
42
|
+
parameters = path_parameters(schema_path)
|
43
|
+
return nil if parameters.empty?
|
44
|
+
|
45
|
+
# If there are regex special characters in the path, the regex will
|
46
|
+
# be too permissive, so escape the non-parameter parts.
|
47
|
+
components = []
|
48
|
+
unprocessed = schema_path.dup
|
49
|
+
parameters.each do |parameter|
|
50
|
+
parts = unprocessed.partition(parameter)
|
51
|
+
components << Regexp.escape(parts[0]) unless parts[0] == ''
|
52
|
+
components << "(?<#{param_name(parameter)}>.+)"
|
53
|
+
unprocessed = parts[2]
|
54
|
+
end
|
55
|
+
components << Regexp.escape(unprocessed) unless unprocessed == ''
|
56
|
+
|
57
|
+
regex = components.join('')
|
58
|
+
matches = request_path.match(regex)
|
59
|
+
return nil unless matches
|
60
|
+
|
61
|
+
# Match up the captured names with the captured values as a hash
|
62
|
+
matches.names.zip(matches.captures).to_h
|
63
|
+
end
|
64
|
+
|
41
65
|
private
|
66
|
+
def path_parameters(schema_path)
|
67
|
+
# OAS3 follows a RFC6570 subset for URL templates
|
68
|
+
# https://swagger.io/docs/specification/serialization/#uri-templates
|
69
|
+
# A URL template param can be preceded optionally by a "." or ";", and can be succeeded optionally by a "*";
|
70
|
+
# this regex returns a match of the full parameter name with all of these modifiers. Ex: {;id*}
|
71
|
+
parameters = schema_path.scan(/(\{[\.;]*[^\{\*\}]+\**\})/)
|
72
|
+
# The `String#scan` method returns an array of arrays; we want an array of strings
|
73
|
+
parameters.collect { |param| param[0] }
|
74
|
+
end
|
75
|
+
|
42
76
|
# check if there is a identical path in the schema (without any param)
|
43
77
|
def matches_directly?(request_path, http_method)
|
44
78
|
@paths.path[request_path]&.operation(http_method)
|
@@ -70,8 +104,9 @@ class OpenAPIParser::PathItemFinder
|
|
70
104
|
splitted_request_path.zip(splitted_schema_path).reduce({}) do |result, zip_item|
|
71
105
|
request_path_item, schema_path_item = zip_item
|
72
106
|
|
73
|
-
|
74
|
-
|
107
|
+
params = parse_path_parameters(schema_path_item, request_path_item)
|
108
|
+
if params
|
109
|
+
result.merge!(params)
|
75
110
|
else
|
76
111
|
return if schema_path_item != request_path_item
|
77
112
|
end
|
@@ -80,7 +115,7 @@ class OpenAPIParser::PathItemFinder
|
|
80
115
|
end
|
81
116
|
end
|
82
117
|
|
83
|
-
# find all matching
|
118
|
+
# find all matching paths with parameters extracted
|
84
119
|
# EXAMPLE:
|
85
120
|
# [
|
86
121
|
# ['/user/{id}/edit', { 'id' => 1 }],
|
@@ -94,23 +129,23 @@ class OpenAPIParser::PathItemFinder
|
|
94
129
|
splitted_schema_path = path.split('/')
|
95
130
|
|
96
131
|
next result if different_depth_or_method?(splitted_schema_path, splitted_request_path, path_item, http_method)
|
97
|
-
|
132
|
+
|
98
133
|
extracted_params = extract_params(splitted_request_path, splitted_schema_path)
|
99
134
|
result << [path, extracted_params] if extracted_params
|
100
135
|
result
|
101
136
|
end
|
102
137
|
end
|
103
138
|
|
104
|
-
# find
|
139
|
+
# find matching path and extract params
|
105
140
|
# EXAMPLE: find_path_and_params('get', '/user/1') => ['/user/{id}', { 'id' => 1 }]
|
106
141
|
def find_path_and_params(http_method, request_path)
|
107
142
|
return [request_path, {}] if matches_directly?(request_path, http_method)
|
108
|
-
|
143
|
+
|
109
144
|
matching = matching_paths_with_params(request_path, http_method)
|
110
145
|
|
111
146
|
# if there are many matching paths, return the one with the smallest number of params
|
112
147
|
# (prefer /user/{id}/action over /user/{param_1}/{param_2} )
|
113
|
-
matching.min_by { |match| match[
|
148
|
+
matching.min_by { |match| match[1].size }
|
114
149
|
end
|
115
150
|
|
116
151
|
def parse_request_path(http_method, request_path)
|
@@ -12,6 +12,7 @@ require_relative 'schema_validators/any_of_validator'
|
|
12
12
|
require_relative 'schema_validators/all_of_validator'
|
13
13
|
require_relative 'schema_validators/one_of_validator'
|
14
14
|
require_relative 'schema_validators/nil_validator'
|
15
|
+
require_relative 'schema_validators/unspecified_type_validator'
|
15
16
|
|
16
17
|
class OpenAPIParser::SchemaValidator
|
17
18
|
# validate value by schema
|
@@ -113,7 +114,7 @@ class OpenAPIParser::SchemaValidator
|
|
113
114
|
when 'array'
|
114
115
|
array_validator
|
115
116
|
else
|
116
|
-
|
117
|
+
unspecified_type_validator
|
117
118
|
end
|
118
119
|
end
|
119
120
|
|
@@ -156,4 +157,8 @@ class OpenAPIParser::SchemaValidator
|
|
156
157
|
def nil_validator
|
157
158
|
@nil_validator ||= OpenAPIParser::SchemaValidator::NilValidator.new(self, @coerce_value)
|
158
159
|
end
|
160
|
+
|
161
|
+
def unspecified_type_validator
|
162
|
+
@unspecified_type_validator ||= OpenAPIParser::SchemaValidator::UnspecifiedTypeValidator.new(self, @coerce_value)
|
163
|
+
end
|
159
164
|
end
|
@@ -4,13 +4,18 @@ class OpenAPIParser::SchemaValidator
|
|
4
4
|
# coerce and validate value
|
5
5
|
# @param [Object] value
|
6
6
|
# @param [OpenAPIParser::Schemas::Schema] schema
|
7
|
-
def coerce_and_validate(value, schema, **
|
7
|
+
def coerce_and_validate(value, schema, **keyword_args)
|
8
8
|
# if any schema return error, it's not valida all of value
|
9
9
|
remaining_keys = value.kind_of?(Hash) ? value.keys : []
|
10
10
|
nested_additional_properties = false
|
11
11
|
schema.all_of.each do |s|
|
12
12
|
# We need to store the reference to all of, so we can perform strict check on allowed properties
|
13
|
-
_coerced, err = validatable.validate_schema(
|
13
|
+
_coerced, err = validatable.validate_schema(
|
14
|
+
value,
|
15
|
+
s,
|
16
|
+
:parent_all_of => true,
|
17
|
+
parent_discriminator_schemas: keyword_args[:parent_discriminator_schemas]
|
18
|
+
)
|
14
19
|
|
15
20
|
if s.type == "object"
|
16
21
|
remaining_keys -= (s.properties || {}).keys
|
@@ -18,7 +18,7 @@ class OpenAPIParser::SchemaValidator
|
|
18
18
|
raise 'need implement'
|
19
19
|
end
|
20
20
|
|
21
|
-
def validate_discriminator_schema(discriminator, value)
|
21
|
+
def validate_discriminator_schema(discriminator, value, parent_discriminator_schemas: [])
|
22
22
|
unless value.key?(discriminator.property_name)
|
23
23
|
return [nil, OpenAPIParser::NotExistDiscriminatorPropertyName.new(discriminator.property_name, value, discriminator.object_reference)]
|
24
24
|
end
|
@@ -34,7 +34,11 @@ class OpenAPIParser::SchemaValidator
|
|
34
34
|
unless resolved_schema
|
35
35
|
return [nil, OpenAPIParser::NotExistDiscriminatorMappedSchema.new(mapping_target, discriminator.object_reference)]
|
36
36
|
end
|
37
|
-
validatable.validate_schema(
|
37
|
+
validatable.validate_schema(
|
38
|
+
value,
|
39
|
+
resolved_schema,
|
40
|
+
**{discriminator_property_name: discriminator.property_name, parent_discriminator_schemas: parent_discriminator_schemas}
|
41
|
+
)
|
38
42
|
end
|
39
43
|
end
|
40
44
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
class OpenAPIParser::SchemaValidator
|
2
2
|
class BooleanValidator < Base
|
3
|
+
include ::OpenAPIParser::SchemaValidator::Enumable
|
4
|
+
|
3
5
|
TRUE_VALUES = ['true', '1'].freeze
|
4
6
|
FALSE_VALUES = ['false', '0'].freeze
|
5
7
|
|
@@ -8,6 +10,9 @@ class OpenAPIParser::SchemaValidator
|
|
8
10
|
|
9
11
|
return OpenAPIParser::ValidateError.build_error_result(value, schema) unless value.kind_of?(TrueClass) || value.kind_of?(FalseClass)
|
10
12
|
|
13
|
+
value, err = check_enum_include(value, schema)
|
14
|
+
return [nil, err] if err
|
15
|
+
|
11
16
|
[value, nil]
|
12
17
|
end
|
13
18
|
|
@@ -21,14 +21,14 @@ class OpenAPIParser::SchemaValidator
|
|
21
21
|
|
22
22
|
value, err = check_enum_include(value, schema)
|
23
23
|
return [nil, err] if err
|
24
|
-
|
24
|
+
|
25
25
|
check_minimum_maximum(value, schema)
|
26
26
|
end
|
27
27
|
|
28
28
|
def coerce(value)
|
29
29
|
Float(value)
|
30
|
-
rescue ArgumentError
|
31
|
-
|
30
|
+
rescue ArgumentError, TypeError
|
31
|
+
value
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -23,12 +23,10 @@ class OpenAPIParser::SchemaValidator
|
|
23
23
|
return value if value.kind_of?(Integer)
|
24
24
|
|
25
25
|
begin
|
26
|
-
|
27
|
-
rescue ArgumentError
|
28
|
-
|
26
|
+
Integer(value)
|
27
|
+
rescue ArgumentError, TypeError
|
28
|
+
value
|
29
29
|
end
|
30
|
-
|
31
|
-
value
|
32
30
|
end
|
33
31
|
end
|
34
32
|
end
|
@@ -4,7 +4,7 @@ class OpenAPIParser::SchemaValidator
|
|
4
4
|
# @param [OpenAPIParser::Schemas::Schema] schema
|
5
5
|
# @param [Boolean] parent_all_of true if component is nested under allOf
|
6
6
|
# @param [String, nil] discriminator_property_name discriminator.property_name to ignore checking additional_properties
|
7
|
-
def coerce_and_validate(value, schema, parent_all_of: false, discriminator_property_name: nil)
|
7
|
+
def coerce_and_validate(value, schema, parent_all_of: false, parent_discriminator_schemas: [], discriminator_property_name: nil)
|
8
8
|
return OpenAPIParser::ValidateError.build_error_result(value, schema) unless value.kind_of?(Hash)
|
9
9
|
|
10
10
|
properties = schema.properties || {}
|
@@ -12,6 +12,16 @@ class OpenAPIParser::SchemaValidator
|
|
12
12
|
required_set = schema.required ? schema.required.to_set : Set.new
|
13
13
|
remaining_keys = value.keys
|
14
14
|
|
15
|
+
if schema.discriminator && !parent_discriminator_schemas.include?(schema)
|
16
|
+
return validate_discriminator_schema(
|
17
|
+
schema.discriminator,
|
18
|
+
value,
|
19
|
+
parent_discriminator_schemas: parent_discriminator_schemas + [schema]
|
20
|
+
)
|
21
|
+
else
|
22
|
+
remaining_keys.delete('discriminator')
|
23
|
+
end
|
24
|
+
|
15
25
|
coerced_values = value.map do |name, v|
|
16
26
|
s = properties[name]
|
17
27
|
coerced, err = if s
|
@@ -30,6 +30,9 @@ class OpenAPIParser::SchemaValidator
|
|
30
30
|
value, err = validate_uuid_format(value, schema)
|
31
31
|
return [nil, err] if err
|
32
32
|
|
33
|
+
value, err = validate_date_format(value, schema)
|
34
|
+
return [nil, err] if err
|
35
|
+
|
33
36
|
[value, nil]
|
34
37
|
end
|
35
38
|
|
@@ -86,5 +89,17 @@ class OpenAPIParser::SchemaValidator
|
|
86
89
|
|
87
90
|
return [nil, OpenAPIParser::InvalidUUIDFormat.new(value, schema.object_reference)]
|
88
91
|
end
|
92
|
+
|
93
|
+
def validate_date_format(value, schema)
|
94
|
+
return [value, nil] unless schema.format == 'date'
|
95
|
+
|
96
|
+
begin
|
97
|
+
Date.strptime(value, "%Y-%m-%d")
|
98
|
+
rescue ArgumentError
|
99
|
+
return [nil, OpenAPIParser::InvalidDateFormat.new(value, schema.object_reference)]
|
100
|
+
end
|
101
|
+
|
102
|
+
return [value, nil]
|
103
|
+
end
|
89
104
|
end
|
90
105
|
end
|
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.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ota42y
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -129,11 +129,11 @@ executables: []
|
|
129
129
|
extensions: []
|
130
130
|
extra_rdoc_files: []
|
131
131
|
files:
|
132
|
+
- ".github/workflows/ci.yaml"
|
132
133
|
- ".gitignore"
|
133
134
|
- ".rspec"
|
134
135
|
- ".rubocop.yml"
|
135
136
|
- ".rubocop_ignore.yml"
|
136
|
-
- ".travis.yml"
|
137
137
|
- CHANGELOG.md
|
138
138
|
- CODE_OF_CONDUCT.md
|
139
139
|
- Gemfile
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- lib/openapi_parser/schema_validators/one_of_validator.rb
|
185
185
|
- lib/openapi_parser/schema_validators/options.rb
|
186
186
|
- lib/openapi_parser/schema_validators/string_validator.rb
|
187
|
+
- lib/openapi_parser/schema_validators/unspecified_type_validator.rb
|
187
188
|
- lib/openapi_parser/schemas.rb
|
188
189
|
- lib/openapi_parser/schemas/base.rb
|
189
190
|
- lib/openapi_parser/schemas/classes.rb
|
@@ -207,7 +208,7 @@ homepage: https://github.com/ota42y/openapi_parser
|
|
207
208
|
licenses:
|
208
209
|
- MIT
|
209
210
|
metadata: {}
|
210
|
-
post_install_message:
|
211
|
+
post_install_message:
|
211
212
|
rdoc_options: []
|
212
213
|
require_paths:
|
213
214
|
- lib
|
@@ -222,8 +223,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
223
|
- !ruby/object:Gem::Version
|
223
224
|
version: '0'
|
224
225
|
requirements: []
|
225
|
-
rubygems_version: 3.
|
226
|
-
signing_key:
|
226
|
+
rubygems_version: 3.2.3
|
227
|
+
signing_key:
|
227
228
|
specification_version: 4
|
228
229
|
summary: OpenAPI3 parser
|
229
230
|
test_files: []
|
data/.travis.yml
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
env:
|
2
|
-
global:
|
3
|
-
- CC_TEST_REPORTER_ID=b49a1717b8ff0aef9eced41d0f87d350a88b46d55083ba2e3df8b6f441ae3fb7
|
4
|
-
|
5
|
-
language: ruby
|
6
|
-
|
7
|
-
rvm:
|
8
|
-
- 2.3.8
|
9
|
-
- 2.4.10
|
10
|
-
- 2.5.8
|
11
|
-
- 2.6.6
|
12
|
-
- 2.7.1
|
13
|
-
- ruby-head
|
14
|
-
|
15
|
-
cache: bundler
|
16
|
-
|
17
|
-
before_script:
|
18
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
19
|
-
- chmod +x ./cc-test-reporter
|
20
|
-
- ./cc-test-reporter before-build
|
21
|
-
|
22
|
-
script: bundle exec rspec
|
23
|
-
|
24
|
-
after_script:
|
25
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
26
|
-
|
27
|
-
notifications:
|
28
|
-
email: false
|
29
|
-
|
30
|
-
sudo: false
|
31
|
-
|
32
|
-
git:
|
33
|
-
depth: 10
|
34
|
-
|
35
|
-
matrix:
|
36
|
-
allow_failures:
|
37
|
-
- rvm: ruby-head
|