openapi_first 1.1.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/openapi_first/body_parser.rb +3 -1
- data/lib/openapi_first/configuration.rb +3 -1
- data/lib/openapi_first/definition/operation.rb +65 -5
- data/lib/openapi_first/definition/path_item.rb +1 -0
- data/lib/openapi_first/definition/request_body.rb +1 -0
- data/lib/openapi_first/definition/response.rb +7 -0
- data/lib/openapi_first/definition.rb +43 -3
- data/lib/openapi_first/error_response.rb +1 -1
- data/lib/openapi_first/errors.rb +6 -0
- data/lib/openapi_first/failure.rb +28 -4
- data/lib/openapi_first/middlewares/request_validation.rb +2 -5
- data/lib/openapi_first/middlewares/response_validation.rb +1 -4
- data/lib/openapi_first/plugins/default/error_response.rb +4 -4
- data/lib/openapi_first/plugins/default.rb +1 -1
- data/lib/openapi_first/plugins/jsonapi/error_response.rb +3 -2
- data/lib/openapi_first/plugins/jsonapi.rb +1 -1
- data/lib/openapi_first/plugins.rb +1 -0
- data/lib/openapi_first/request_validation/request_body_validator.rb +1 -1
- data/lib/openapi_first/request_validation/validator.rb +1 -0
- data/lib/openapi_first/response_validation/validator.rb +1 -0
- data/lib/openapi_first/runtime_request.rb +63 -3
- data/lib/openapi_first/runtime_response.rb +43 -4
- data/lib/openapi_first/schema/validation_error.rb +2 -0
- data/lib/openapi_first/schema/validation_result.rb +2 -7
- data/lib/openapi_first/schema.rb +1 -0
- data/lib/openapi_first/version.rb +1 -1
- data/lib/openapi_first.rb +21 -3
- metadata +6 -17
- data/.github/CODEOWNERS +0 -1
- data/.github/workflows/ruby.yml +0 -13
- data/.gitignore +0 -11
- data/CHANGELOG.md +0 -274
- data/Gemfile +0 -18
- data/Gemfile.lock +0 -170
- data/Gemfile.rack2 +0 -15
- data/Gemfile.rack2.lock +0 -99
- data/LICENSE.txt +0 -21
- data/README.md +0 -225
- data/openapi_first.gemspec +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: caea1ca3e63935e0d04a52bade49e9f8270da3bdcf3b3cb89e3791cc202c1a79
|
4
|
+
data.tar.gz: 3d1da5e269e0328ec383b30cf29486b1d49aa91317e428626c26f9284eb1d55c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a48588e004db687e0dee2b54982837aebe3dcb3d65cf3191141b59d7f63d945083dd0bc364346acaa4442420101310ffc174383ee6e2897468b6680f90c4172
|
7
|
+
data.tar.gz: 352789bc86107fc3253cb08a3771399e5ecee50189c119903bc678f1de7eb078a6bc89a797bc22322ae52beb3de30c64de612fb6350d572cc6a6a1c1cb6fd067
|
@@ -3,10 +3,12 @@
|
|
3
3
|
require 'multi_json'
|
4
4
|
|
5
5
|
module OpenapiFirst
|
6
|
+
# @!visibility private
|
6
7
|
class BodyParser
|
7
8
|
def self.const_missing(const_name)
|
8
9
|
super unless const_name == :ParsingError
|
9
|
-
warn 'DEPRECATION WARNING: OpenapiFirst::BodyParser::ParsingError is deprecated.
|
10
|
+
warn 'DEPRECATION WARNING: OpenapiFirst::BodyParser::ParsingError is deprecated. ' \
|
11
|
+
'Use OpenapiFirst::ParseError instead.'
|
10
12
|
OpenapiFirst::ParseError
|
11
13
|
end
|
12
14
|
|
@@ -1,13 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module OpenapiFirst
|
4
|
+
# Global configuration. Currently only used for the request validation middleware.
|
4
5
|
class Configuration
|
5
6
|
def initialize
|
6
7
|
@request_validation_error_response = OpenapiFirst.plugin(:default)::ErrorResponse
|
7
8
|
@request_validation_raise_error = false
|
8
9
|
end
|
9
10
|
|
10
|
-
attr_reader :request_validation_error_response
|
11
|
+
attr_reader :request_validation_error_response
|
12
|
+
attr_accessor :request_validation_raise_error
|
11
13
|
|
12
14
|
def request_validation_error_response=(mod)
|
13
15
|
@request_validation_error_response = if mod.is_a?(Symbol)
|
@@ -8,11 +8,14 @@ require_relative 'responses'
|
|
8
8
|
|
9
9
|
module OpenapiFirst
|
10
10
|
class Definition
|
11
|
+
# Represents an operation object in the OpenAPI 3.X specification.
|
12
|
+
# Use this class to access information about the operation. Use `#[key]` to read the raw data.
|
13
|
+
# When using the middleware you can access the operation object via `env[OpenapiFirst::REQUEST].operation`.
|
11
14
|
class Operation
|
12
15
|
extend Forwardable
|
16
|
+
|
13
17
|
def_delegators :operation_object,
|
14
|
-
:[]
|
15
|
-
:dig
|
18
|
+
:[]
|
16
19
|
|
17
20
|
WRITE_METHODS = Set.new(%w[post put patch delete]).freeze
|
18
21
|
private_constant :WRITE_METHODS
|
@@ -25,31 +28,62 @@ module OpenapiFirst
|
|
25
28
|
@operation_object = @path_item_object[request_method]
|
26
29
|
end
|
27
30
|
|
28
|
-
|
31
|
+
# Returns the path of the operation as in the API description.
|
32
|
+
# @return [String] The path of the operation.
|
33
|
+
attr_reader :path
|
34
|
+
|
35
|
+
# Returns the (downcased) request method of the operation.
|
36
|
+
# Example: "get"
|
37
|
+
# @return [String] The request method of the operation.
|
38
|
+
attr_reader :method
|
29
39
|
alias request_method method
|
30
40
|
|
41
|
+
attr_reader :openapi_version # :nodoc:
|
42
|
+
|
43
|
+
# Returns the operation ID as defined in the API description.
|
44
|
+
# @return [String, nil]
|
31
45
|
def operation_id
|
32
46
|
operation_object['operationId']
|
33
47
|
end
|
34
48
|
|
49
|
+
# Checks if the operation is a read operation.
|
50
|
+
# This is the case for all request methods except POST, PUT, PATCH and DELETE.
|
51
|
+
# @return [Boolean] `true` if the operation is a read operation, `false` otherwise.
|
35
52
|
def read?
|
36
53
|
!write?
|
37
54
|
end
|
38
55
|
|
56
|
+
# Checks if the operation is a write operation.
|
57
|
+
# This is the case for POST, PUT, PATCH and DELETE request methods.
|
58
|
+
# @return [Boolean] `true` if the operation is a write operation, `false` otherwise.
|
39
59
|
def write?
|
40
60
|
WRITE_METHODS.include?(method)
|
41
61
|
end
|
42
62
|
|
63
|
+
# Returns the request body definition if defined in the API description.
|
64
|
+
# @return [RequestBody, nil] The request body of the operation, or `nil` if not present.
|
43
65
|
def request_body
|
44
66
|
@request_body ||= RequestBody.new(operation_object['requestBody'], self) if operation_object['requestBody']
|
45
67
|
end
|
46
68
|
|
69
|
+
# Checks if a response status is defined for this operation.
|
70
|
+
# @param status [Integer, String] The response status to check.
|
71
|
+
# @return [Boolean] `true` if the response status is defined, `false` otherwise.
|
47
72
|
def response_status_defined?(status)
|
48
73
|
responses.status_defined?(status)
|
49
74
|
end
|
50
75
|
|
51
|
-
|
76
|
+
# Returns the response object for a given status.
|
77
|
+
# @param status [Integer, String] The response status.
|
78
|
+
# @param content_type [String] Content-Type of the current response.
|
79
|
+
# @return [Response, nil] The response object for the given status, or `nil` if not found.
|
80
|
+
def response_for(status, content_type)
|
81
|
+
responses.response_for(status, content_type)
|
82
|
+
end
|
52
83
|
|
84
|
+
# Returns the schema for a given content type.
|
85
|
+
# @param content_type [String] The content type.
|
86
|
+
# @return [Schema, nil] The schema for the given content type, or `nil` if not found.
|
53
87
|
def schema_for(content_type)
|
54
88
|
content = @request_body_object['content']
|
55
89
|
return unless content&.any?
|
@@ -60,46 +94,72 @@ module OpenapiFirst
|
|
60
94
|
end
|
61
95
|
end
|
62
96
|
|
97
|
+
# Returns a unique name for this operation. Used for generating error messages.
|
98
|
+
# @visibility private
|
63
99
|
def name
|
64
100
|
@name ||= "#{method.upcase} #{path} (#{operation_id})"
|
65
101
|
end
|
66
102
|
|
103
|
+
# Returns the path parameters of the operation.
|
104
|
+
# @return [Array<Hash>] The path parameters of the operation.
|
67
105
|
def path_parameters
|
68
106
|
all_parameters['path']
|
69
107
|
end
|
70
108
|
|
109
|
+
# Returns the query parameters of the operation.
|
110
|
+
# Returns parameters defined on the path and in the operation.
|
111
|
+
# @return [Array<Hash>] The query parameters of the operation.
|
71
112
|
def query_parameters
|
72
113
|
all_parameters['query']
|
73
114
|
end
|
74
115
|
|
116
|
+
# Returns the header parameters of the operation.
|
117
|
+
# Returns parameters defined on the path and in the operation.
|
118
|
+
# @return [Array<Hash>] The header parameters of the operation.
|
75
119
|
def header_parameters
|
76
120
|
all_parameters['header']
|
77
121
|
end
|
78
122
|
|
123
|
+
# Returns the cookie parameters of the operation.
|
124
|
+
# Returns parameters defined on the path and in the operation.
|
125
|
+
# @return [Array<Hash>] The cookie parameters of the operation.
|
79
126
|
def cookie_parameters
|
80
127
|
all_parameters['cookie']
|
81
128
|
end
|
82
129
|
|
130
|
+
# Returns the schema for the path parameters.
|
131
|
+
# @visibility private
|
132
|
+
# @return [Schema, nil] The schema for the path parameters, or `nil` if not found.
|
83
133
|
def path_parameters_schema
|
84
134
|
@path_parameters_schema ||= build_schema(path_parameters)
|
85
135
|
end
|
86
136
|
|
137
|
+
# Returns the schema for the query parameters.
|
138
|
+
# @visibility private
|
139
|
+
# @return [Schema, nil] The schema for the query parameters, or `nil` if not found.
|
87
140
|
def query_parameters_schema
|
88
141
|
@query_parameters_schema ||= build_schema(query_parameters)
|
89
142
|
end
|
90
143
|
|
144
|
+
# Returns the schema for the header parameters.
|
145
|
+
# @visibility private
|
146
|
+
# @return [Schema, nil] The schema for the header parameters, or `nil` if not found.
|
91
147
|
def header_parameters_schema
|
92
148
|
@header_parameters_schema ||= build_schema(header_parameters)
|
93
149
|
end
|
94
150
|
|
151
|
+
# Returns the schema for the cookie parameters.
|
152
|
+
# @visibility private
|
153
|
+
# @return [Schema, nil] The schema for the cookie parameters, or `nil` if not found.
|
95
154
|
def cookie_parameters_schema
|
96
155
|
@cookie_parameters_schema ||= build_schema(cookie_parameters)
|
97
156
|
end
|
98
157
|
|
99
158
|
private
|
100
159
|
|
160
|
+
WRITE_METHODS = Set.new(%w[post put patch delete]).freeze
|
161
|
+
|
101
162
|
IGNORED_HEADERS = Set['Content-Type', 'Accept', 'Authorization'].freeze
|
102
|
-
private_constant :IGNORED_HEADERS
|
103
163
|
|
104
164
|
def all_parameters
|
105
165
|
@all_parameters ||= (@path_item_object.fetch('parameters', []) + operation_object.fetch('parameters', []))
|
@@ -4,6 +4,7 @@ require_relative '../schema'
|
|
4
4
|
|
5
5
|
module OpenapiFirst
|
6
6
|
class Definition
|
7
|
+
# Represents a request body definition in the OpenAPI document that belongs to an operation.
|
7
8
|
class RequestBody
|
8
9
|
def initialize(request_body_object, operation)
|
9
10
|
@request_body_object = request_body_object
|
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
module OpenapiFirst
|
4
4
|
class Definition
|
5
|
+
# Represents a response definition in the OpenAPI document.
|
6
|
+
# This is not a direct reflecton of the OpenAPI 3.X response definition, but a combination of
|
7
|
+
# status, content type and content schema.
|
5
8
|
class Response
|
6
9
|
def initialize(operation:, status:, response_object:, content_type:, content_schema:)
|
7
10
|
@operation = operation
|
@@ -11,6 +14,10 @@ module OpenapiFirst
|
|
11
14
|
@content_schema = content_schema
|
12
15
|
end
|
13
16
|
|
17
|
+
# @attr_reader [Operation] operation The operation this response belongs to.
|
18
|
+
# @attr_reader [Integer] status The HTTP status code of the response definition.
|
19
|
+
# @attr_reader [String, nil] content_type Content type of this response.
|
20
|
+
# @attr_reader [Schema, nil] content_schema the Schema of the response body.
|
14
21
|
attr_reader :operation, :status, :content_type, :content_schema
|
15
22
|
|
16
23
|
def headers
|
@@ -1,20 +1,47 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'mustermann
|
3
|
+
require 'mustermann'
|
4
4
|
require_relative 'definition/path_item'
|
5
5
|
require_relative 'runtime_request'
|
6
|
+
require_relative 'request_validation/validator'
|
7
|
+
require_relative 'response_validation/validator'
|
6
8
|
|
7
9
|
module OpenapiFirst
|
8
10
|
# Represents an OpenAPI API Description document
|
11
|
+
# This is returned by OpenapiFirst.load.
|
9
12
|
class Definition
|
10
13
|
attr_reader :filepath, :paths, :openapi_version
|
11
14
|
|
12
|
-
|
15
|
+
# @param resolved [Hash] The resolved OpenAPI document.
|
16
|
+
# @param filepath [String] The file path of the OpenAPI document.
|
17
|
+
def initialize(resolved, filepath = nil)
|
13
18
|
@filepath = filepath
|
14
19
|
@paths = resolved['paths']
|
15
20
|
@openapi_version = detect_version(resolved)
|
16
21
|
end
|
17
22
|
|
23
|
+
# Validates the request against the API description.
|
24
|
+
# @param rack_request [Rack::Request] The Rack request object.
|
25
|
+
# @param raise_error [Boolean] Whether to raise an error if validation fails.
|
26
|
+
# @return [RuntimeRequest] The validated request object.
|
27
|
+
def validate_request(rack_request, raise_error: false)
|
28
|
+
validated = request(rack_request).tap(&:validate)
|
29
|
+
validated.error&.raise! if raise_error
|
30
|
+
validated
|
31
|
+
end
|
32
|
+
|
33
|
+
# Validates the response against the API description.
|
34
|
+
# @param rack_request [Rack::Request] The Rack request object.
|
35
|
+
# @param rack_response [Rack::Response] The Rack response object.
|
36
|
+
# @param raise_error [Boolean] Whether to raise an error if validation fails.
|
37
|
+
# @return [RuntimeResponse] The validated response object.
|
38
|
+
def validate_response(rack_request, rack_response, raise_error: false)
|
39
|
+
request(rack_request).validate_response(rack_response, raise_error:)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Builds a RuntimeRequest object based on the Rack request.
|
43
|
+
# @param rack_request [Rack::Request] The Rack request object.
|
44
|
+
# @return [RuntimeRequest] The RuntimeRequest object.
|
18
45
|
def request(rack_request)
|
19
46
|
path_item, path_params = find_path_item_and_params(rack_request.path)
|
20
47
|
operation = path_item&.operation(rack_request.request_method.downcase)
|
@@ -26,14 +53,25 @@ module OpenapiFirst
|
|
26
53
|
)
|
27
54
|
end
|
28
55
|
|
56
|
+
# Builds a RuntimeResponse object based on the Rack request and response.
|
57
|
+
# @param rack_request [Rack::Request] The Rack request object.
|
58
|
+
# @param rack_response [Rack::Response] The Rack response object.
|
59
|
+
# @return [RuntimeResponse] The RuntimeResponse object.
|
29
60
|
def response(rack_request, rack_response)
|
30
61
|
request(rack_request).response(rack_response)
|
31
62
|
end
|
32
63
|
|
64
|
+
# Gets all the operations defined in the API description.
|
65
|
+
# @return [Array<Operation>] An array of Operation objects.
|
33
66
|
def operations
|
34
67
|
@operations ||= path_items.flat_map(&:operations)
|
35
68
|
end
|
36
69
|
|
70
|
+
# Gets the PathItem object for the specified path.
|
71
|
+
# @param pathname [String] The path template string.
|
72
|
+
# @return [PathItem] The PathItem object.
|
73
|
+
# Example:
|
74
|
+
# definition.path('/pets/{id}')
|
37
75
|
def path(pathname)
|
38
76
|
return unless paths.key?(pathname)
|
39
77
|
|
@@ -42,6 +80,8 @@ module OpenapiFirst
|
|
42
80
|
|
43
81
|
private
|
44
82
|
|
83
|
+
# Gets all the PathItem objects defined in the API description.
|
84
|
+
# @return [Array] An array of PathItem objects.
|
45
85
|
def path_items
|
46
86
|
@path_items ||= paths.flat_map do |path, path_item_object|
|
47
87
|
PathItem.new(path, path_item_object, openapi_version:)
|
@@ -60,7 +100,7 @@ module OpenapiFirst
|
|
60
100
|
|
61
101
|
def search_for_path_item(request_path)
|
62
102
|
paths.find do |path, path_item_object|
|
63
|
-
template = Mustermann
|
103
|
+
template = Mustermann.new(path)
|
64
104
|
path_params = template.params(request_path)
|
65
105
|
next unless path_params
|
66
106
|
next unless path_params.size == template.names.size
|
data/lib/openapi_first/errors.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module OpenapiFirst
|
4
|
+
# @!visibility private
|
4
5
|
class Error < StandardError; end
|
6
|
+
# @!visibility private
|
5
7
|
class ParseError < Error; end
|
8
|
+
# @!visibility private
|
6
9
|
class NotFoundError < Error; end
|
10
|
+
# @!visibility private
|
7
11
|
class RequestInvalidError < Error; end
|
12
|
+
# @!visibility private
|
8
13
|
class ResponseNotFoundError < Error; end
|
14
|
+
# @!visibility private
|
9
15
|
class ResponseInvalidError < Error; end
|
10
16
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module OpenapiFirst
|
4
|
+
# A failure object returned when validation of request or response has failed.
|
4
5
|
class Failure
|
5
6
|
FAILURE = :openapi_first_validation_failure
|
6
7
|
|
@@ -29,7 +30,7 @@ module OpenapiFirst
|
|
29
30
|
)
|
30
31
|
end
|
31
32
|
|
32
|
-
# @param
|
33
|
+
# @param error_type [Symbol] See TYPES.keys
|
33
34
|
# @param message [String] A generic error message
|
34
35
|
# @param errors [Array<OpenapiFirst::Schema::ValidationError>]
|
35
36
|
def initialize(error_type, message: nil, errors: nil)
|
@@ -43,13 +44,36 @@ module OpenapiFirst
|
|
43
44
|
@errors = errors
|
44
45
|
end
|
45
46
|
|
46
|
-
attr_reader
|
47
|
+
# @attr_reader [Symbol] error_type The type of the failure. See TYPES.keys.
|
48
|
+
# @alias type error_type
|
49
|
+
# Example: :invalid_body
|
50
|
+
attr_reader :error_type
|
51
|
+
alias type error_type
|
52
|
+
|
53
|
+
# @attr_reader [String] message A generic error message
|
54
|
+
attr_reader :message
|
55
|
+
|
56
|
+
# @attr_reader [Array<OpenapiFirst::Schema::ValidationError>] errors Schema validation errors
|
57
|
+
attr_reader :errors
|
47
58
|
|
48
59
|
# Raise an exception that fits the failure.
|
49
60
|
def raise!
|
50
|
-
exception,
|
61
|
+
exception, = TYPES.fetch(error_type)
|
62
|
+
raise exception, exception_message
|
63
|
+
end
|
64
|
+
|
65
|
+
def exception_message
|
66
|
+
_, message_prefix = TYPES.fetch(error_type)
|
67
|
+
|
68
|
+
"#{message_prefix} #{@message || generate_message}"
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
51
72
|
|
52
|
-
|
73
|
+
def generate_message
|
74
|
+
messages = errors&.take(4)&.map(&:error)
|
75
|
+
messages << "... (#{errors.size} errors total)" if errors && errors.size > 4
|
76
|
+
messages&.join('. ')
|
53
77
|
end
|
54
78
|
end
|
55
79
|
end
|
@@ -26,11 +26,8 @@ module OpenapiFirst
|
|
26
26
|
request = find_request(env)
|
27
27
|
return @app.call(env) unless request
|
28
28
|
|
29
|
-
failure =
|
30
|
-
|
31
|
-
else
|
32
|
-
request.validate
|
33
|
-
end
|
29
|
+
failure = request.validate
|
30
|
+
failure.raise! if failure && @raise
|
34
31
|
return @error_response_class.new(failure:).render if failure
|
35
32
|
|
36
33
|
@app.call(env)
|
@@ -20,11 +20,8 @@ module OpenapiFirst
|
|
20
20
|
def call(env)
|
21
21
|
request = find_request(env)
|
22
22
|
status, headers, body = @app.call(env)
|
23
|
-
|
24
23
|
body = body.to_ary if body.respond_to?(:to_ary)
|
25
|
-
|
26
|
-
request.response(Rack::Response[status, headers, body]).validate!
|
27
|
-
|
24
|
+
request.validate_response(Rack::Response[status, headers, body], raise_error: true)
|
28
25
|
[status, headers, body]
|
29
26
|
end
|
30
27
|
|
@@ -29,10 +29,10 @@ module OpenapiFirst
|
|
29
29
|
MultiJson.dump(result)
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
32
|
+
def type = failure.type
|
33
33
|
|
34
34
|
def title
|
35
|
-
TITLES.fetch(
|
35
|
+
TITLES.fetch(type)
|
36
36
|
end
|
37
37
|
|
38
38
|
def content_type
|
@@ -51,7 +51,7 @@ module OpenapiFirst
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def pointer_key
|
54
|
-
case
|
54
|
+
case type
|
55
55
|
when :invalid_body
|
56
56
|
:pointer
|
57
57
|
when :invalid_query, :invalid_path
|
@@ -64,7 +64,7 @@ module OpenapiFirst
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def pointer(data_pointer)
|
67
|
-
return data_pointer if
|
67
|
+
return data_pointer if type == :invalid_body
|
68
68
|
|
69
69
|
data_pointer.delete_prefix('/')
|
70
70
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module OpenapiFirst
|
4
4
|
module Plugins
|
5
5
|
module Jsonapi
|
6
|
+
# A JSON:API conform error response. See https://jsonapi.org/.
|
6
7
|
class ErrorResponse
|
7
8
|
include OpenapiFirst::ErrorResponse
|
8
9
|
|
@@ -36,7 +37,7 @@ module OpenapiFirst
|
|
36
37
|
end
|
37
38
|
|
38
39
|
def pointer_key
|
39
|
-
case failure.
|
40
|
+
case failure.type
|
40
41
|
when :invalid_body
|
41
42
|
:pointer
|
42
43
|
when :invalid_query, :invalid_path
|
@@ -49,7 +50,7 @@ module OpenapiFirst
|
|
49
50
|
end
|
50
51
|
|
51
52
|
def pointer(data_pointer)
|
52
|
-
return data_pointer if failure.
|
53
|
+
return data_pointer if failure.type == :invalid_body
|
53
54
|
|
54
55
|
data_pointer.delete_prefix('/')
|
55
56
|
end
|