openapi_first 1.1.1 → 1.3.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/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
|