openapi_parser 0.11.2 → 0.14.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yaml +17 -0
- data/.gitignore +4 -1
- data/CHANGELOG.md +26 -0
- data/README.md +1 -3
- data/lib/openapi_parser.rb +5 -0
- data/lib/openapi_parser/concerns/findable.rb +8 -5
- data/lib/openapi_parser/concerns/parameter_validatable.rb +7 -1
- data/lib/openapi_parser/errors.rb +27 -16
- data/lib/openapi_parser/path_item_finder.rb +42 -7
- data/lib/openapi_parser/request_operation.rb +0 -1
- 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/schemas/path_item.rb +4 -2
- 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: af992ada1b5830b3d4cbc00e0ccaf5a852689a744af4d239887b3dc5c8be27ec
|
4
|
+
data.tar.gz: adbd6263d7f27fecf43da5881d8c06e5bf23307c94271e2b0d7fe86aa5e0c402
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c14c69ad8074807efdc4a3016cfec14fc62635c893c28839089531ad91239b41ad418fc182e32252eebaca02d4a38286c58e81fa1a0be5b43190301601edf2e4
|
7
|
+
data.tar.gz: ebd2d353112df3ac9a5a013b6ee4a7a53ea2b9817a6f46653ee619959d667bcbd6591e763ffcd0075f55b3db373a4e515ca84949275efbedf2fb8dcbfab809b9
|
@@ -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,31 @@
|
|
1
1
|
## Unreleased
|
2
2
|
|
3
|
+
## 0.14.1 (2021-07-9)
|
4
|
+
### Fixed
|
5
|
+
* Fix bug for using path parameter and coerce option #115
|
6
|
+
|
7
|
+
## 0.14.0 (2021-05-24)
|
8
|
+
|
9
|
+
### Added
|
10
|
+
* Add basic polymorphism handling #103
|
11
|
+
* Support empty schema as any type #109
|
12
|
+
* Add date format validation for string #102
|
13
|
+
|
14
|
+
### Fixed
|
15
|
+
* Fix anyOf coercion to float and integer when value is a non-string type #110
|
16
|
+
|
17
|
+
## 0.13.0 (2021-05-01)
|
18
|
+
* Fix a problem with remote reference to path items which have path parameters #95
|
19
|
+
* Support enum for booleans. #104
|
20
|
+
|
21
|
+
## 0.12.1 (2020-08-27)
|
22
|
+
* Use CGI.unescape (warning fix) #92
|
23
|
+
|
24
|
+
## 0.12.0 (2020-08-26)
|
25
|
+
* Find path by extracted params than path length #84
|
26
|
+
* Unescape ref URI before lookup in OpenAPIParser::Findable #85
|
27
|
+
* Improved path parameter matching code to allow file extensions, multiple parameters inside one path element, etc #90
|
28
|
+
|
3
29
|
## 0.11.2 (2020-05-23)
|
4
30
|
* Allow date and time content in YAML #81
|
5
31
|
|
data/README.md
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
# OpenAPI Parser
|
2
|
-
[![
|
2
|
+
[![ci](https://github.com/ota42y/openapi_parser/actions/workflows/ci.yaml/badge.svg)](https://github.com/ota42y/openapi_parser/actions/workflows/ci.yaml)
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/openapi_parser.svg)](https://badge.fury.io/rb/openapi_parser)
|
4
4
|
[![Yard Docs](https://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/gems/openapi_parser)
|
5
|
-
[![Maintainability](https://api.codeclimate.com/v1/badges/62bad4bcb3f691d46487/maintainability)](https://codeclimate.com/github/ota42y/openapi_parser/maintainability)
|
6
|
-
[![Test Coverage](https://api.codeclimate.com/v1/badges/62bad4bcb3f691d46487/test_coverage)](https://codeclimate.com/github/ota42y/openapi_parser/test_coverage)
|
7
5
|
[![Inch CI](https://inch-ci.org/github/ota42y/openapi_parser.svg?branch=master)](https://inch-ci.org/github/ota42y/openapi_parser)
|
8
6
|
|
9
7
|
This is OpenAPI3 parser and validator.
|
data/lib/openapi_parser.rb
CHANGED
@@ -93,6 +93,11 @@ module OpenAPIParser
|
|
93
93
|
|
94
94
|
OpenAPIParser::ReferenceExpander.expand(root) if config.expand_reference
|
95
95
|
|
96
|
+
# TODO: use callbacks
|
97
|
+
root.paths&.path&.values&.each do | path_item |
|
98
|
+
path_item.set_path_item_to_operation
|
99
|
+
end
|
100
|
+
|
96
101
|
root
|
97
102
|
end
|
98
103
|
end
|
@@ -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,6 +13,12 @@ module OpenAPIParser::ParameterValidatable
|
|
13
13
|
validate_query_parameter(params, object_reference, options)
|
14
14
|
end
|
15
15
|
|
16
|
+
# @param [PathItem] path_item parent
|
17
|
+
def set_parent_path_item(path_item)
|
18
|
+
@merged_parameter = (parameters || []) + (path_item.parameters || [])
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
16
22
|
private
|
17
23
|
|
18
24
|
# @param [Hash] params query parameter hash
|
@@ -44,7 +50,7 @@ module OpenAPIParser::ParameterValidatable
|
|
44
50
|
# @return [Hash{String => Hash{String => Parameter}}] hash[in][name] => Parameter
|
45
51
|
def divided_parameter_hash
|
46
52
|
@divided_parameter_hash ||=
|
47
|
-
(
|
53
|
+
(@merged_parameter || []).
|
48
54
|
group_by(&:in).
|
49
55
|
map { |in_type, params| # rubocop:disable Style/BlockDelimiters
|
50
56
|
[
|
@@ -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)
|
@@ -65,7 +65,6 @@ class OpenAPIParser::RequestOperation
|
|
65
65
|
# @param [OpenAPIParser::SchemaValidator::Options] options request validator options
|
66
66
|
def validate_request_parameter(params, headers, options = nil)
|
67
67
|
options ||= config.request_validator_options
|
68
|
-
path_item&.validate_request_parameter(params, headers, options)
|
69
68
|
operation_object&.validate_request_parameter(params, headers, options)
|
70
69
|
end
|
71
70
|
|
@@ -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
|
@@ -3,8 +3,6 @@
|
|
3
3
|
|
4
4
|
module OpenAPIParser::Schemas
|
5
5
|
class PathItem < Base
|
6
|
-
include OpenAPIParser::ParameterValidatable
|
7
|
-
|
8
6
|
openapi_attr_values :summary, :description
|
9
7
|
|
10
8
|
openapi_attr_objects :get, :put, :post, :delete, :options, :head, :patch, :trace, Operation
|
@@ -16,5 +14,9 @@ module OpenAPIParser::Schemas
|
|
16
14
|
rescue NoMethodError
|
17
15
|
nil
|
18
16
|
end
|
17
|
+
|
18
|
+
def set_path_item_to_operation
|
19
|
+
[:get, :put, :post, :delete, :options, :head, :patch, :trace].each{ |method| operation(method)&.set_parent_path_item(self)}
|
20
|
+
end
|
19
21
|
end
|
20
22
|
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.1
|
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-07-09 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
|