openapi_first 2.6.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/README.md +43 -11
- data/lib/openapi_first/builder.rb +0 -2
- data/lib/openapi_first/configuration.rb +2 -1
- data/lib/openapi_first/definition.rb +29 -2
- data/lib/openapi_first/test/coverage/plan.rb +4 -3
- data/lib/openapi_first/test/coverage/terminal_formatter.rb +1 -2
- data/lib/openapi_first/test/coverage.rb +3 -3
- data/lib/openapi_first/test/methods.rb +41 -8
- data/lib/openapi_first/test/minitest_helpers.rb +1 -1
- data/lib/openapi_first/test/plain_helpers.rb +1 -1
- data/lib/openapi_first/test.rb +13 -8
- data/lib/openapi_first/version.rb +1 -1
- data/lib/openapi_first.rb +10 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 177998c88421283a6868e3aa9c5bbbe1eea702bc8b65abb22c28795cb2b7b6a2
|
4
|
+
data.tar.gz: 603118b530e39957ea95086d98a95362e9eb9b9490a63adc7c2bc8e0f7ba7846
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58aac32a5c8d7433414f4bf0f2cbf8142376c76d9ad918bf06531f40da0206e870a12e36718ca7763dd273ea18b664799f22acff84df143e36591a19284895fd
|
7
|
+
data.tar.gz: cba873da9fa8b1bf957a47fe34dcd30c50af51185dc83ba78c3f78ad2d5630399555c7d81f89f6e7cb96d9c56771c55aa956900249c2a6700d88869233339f6d
|
data/CHANGELOG.md
CHANGED
@@ -2,10 +2,16 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## 2.7.0
|
6
|
+
|
7
|
+
- Allow to override path for schema matching with `config.path = ->(request) { '/prefix' + request.path } ` (https://github.com/ahx/openapi_first/issues/349)
|
8
|
+
- Support passing in a Definition instance when registering an OAD for tests (https://github.com/ahx/openapi_first/issues/353)
|
9
|
+
- Fix registering multiple APIs for testing (https://github.com/ahx/openapi_first/issues/352)
|
10
|
+
|
5
11
|
## 2.6.0
|
6
12
|
|
7
13
|
- Middlewares now accept the OAD as a first positional argument instead of `:spec` inside the options hash.
|
8
|
-
- No longer merge parameter schemas of the same location (for example "query") in order to fix [#320](https://github.com/ahx/openapi_first/issues/320).
|
14
|
+
- No longer merge parameter schemas of the same location (for example "query") in order to fix [#320](https://github.com/ahx/openapi_first/issues/320).
|
9
15
|
- `OpenapiFirst::Test::Methods[MyApplication]` returns a Module which adds an `app` method to be used by rack-test alonside the `assert_api_conform` method.
|
10
16
|
- Make default coverage report less verbose
|
11
17
|
The default formatter (TerminalFormatter) no longer prints all un-requested requests by default. You can set `test.coverage_formatter_options = { focused: false }` to get back the old behavior
|
data/README.md
CHANGED
@@ -19,6 +19,7 @@ You can use openapi_first on production for [request validation](#request-valida
|
|
19
19
|
- [Configuration](#configuration)
|
20
20
|
- [Hooks](#hooks)
|
21
21
|
- [Alternatives](#alternatives)
|
22
|
+
- [Frequently Asked Questions](#frequently-asked-questions)
|
22
23
|
- [Development](#development)
|
23
24
|
- [Benchmarks](#benchmarks)
|
24
25
|
- [Contributing](#contributing)
|
@@ -29,13 +30,13 @@ You can use openapi_first on production for [request validation](#request-valida
|
|
29
30
|
|
30
31
|
### Request validation
|
31
32
|
|
32
|
-
The request validation middleware returns a 4xx if the request is invalid or not defined in the API description. It adds a request object to the current Rack environment at `env[OpenapiFirst::REQUEST]` with the request parameters parsed
|
33
|
+
The request validation middleware returns a 4xx if the request is invalid or not defined in the API description. It adds a request object to the current Rack environment at `env[OpenapiFirst::REQUEST]` with the request parameters parsed exactly as described in your API description plus access to meta information from your API description. See _[Manual use](#manual-use)_ for more details about that object.
|
33
34
|
|
34
35
|
```ruby
|
35
|
-
use OpenapiFirst::Middlewares::RequestValidation,
|
36
|
+
use OpenapiFirst::Middlewares::RequestValidation, 'openapi.yaml'
|
36
37
|
|
37
38
|
# Pass `raise_error: true` to raise an error if request is invalid:
|
38
|
-
use OpenapiFirst::Middlewares::RequestValidation,
|
39
|
+
use OpenapiFirst::Middlewares::RequestValidation, 'openapi.yaml', raise_error: true
|
39
40
|
```
|
40
41
|
|
41
42
|
#### Error responses
|
@@ -73,7 +74,7 @@ content-type: "application/problem+json"
|
|
73
74
|
openapi_first offers a [JSON:API](https://jsonapi.org/) error response by passing `error_response: :jsonapi`:
|
74
75
|
|
75
76
|
```ruby
|
76
|
-
use OpenapiFirst::Middlewares::RequestValidation,
|
77
|
+
use OpenapiFirst::Middlewares::RequestValidation, 'openapi.yaml, error_response: :jsonapi'
|
77
78
|
```
|
78
79
|
|
79
80
|
<details>
|
@@ -126,10 +127,10 @@ This middleware raises an error by default if the response is not valid.
|
|
126
127
|
This can be useful in a test or staging environment, especially if you are adopting OpenAPI for an existing implementation.
|
127
128
|
|
128
129
|
```ruby
|
129
|
-
use OpenapiFirst::Middlewares::ResponseValidation,
|
130
|
+
use OpenapiFirst::Middlewares::ResponseValidation, 'openapi.yaml' if ENV['RACK_ENV'] == 'test'
|
130
131
|
|
131
132
|
# Pass `raise_error: false` to not raise an error:
|
132
|
-
use OpenapiFirst::Middlewares::ResponseValidation,
|
133
|
+
use OpenapiFirst::Middlewares::ResponseValidation, 'openapi.yaml', raise_error: false
|
133
134
|
```
|
134
135
|
|
135
136
|
If you are adopting OpenAPI you can use these options together with [hooks](#hooks) to get notified about requests/responses that do match your API description.
|
@@ -149,13 +150,13 @@ To make sure your _whole_ API description is implemented, openapi_first ships wi
|
|
149
150
|
> [!NOTE]
|
150
151
|
> This is a brand new feature. ✨ Your feedback is very welcome.
|
151
152
|
|
152
|
-
This feature tracks all requests/
|
153
|
+
This feature tracks all requests/responses that are validated via openapi_first and tells you about which request/responses are missing.
|
153
154
|
Here is how to set it up with [rack-test](https://github.com/rack/rack-test):
|
154
155
|
|
155
156
|
1. Register all OpenAPI documents to track coverage for. This should go at the top of your test helper file before loading your application code.
|
156
157
|
```ruby
|
157
158
|
require 'openapi_first'
|
158
|
-
OpenapiFirst::Test.setup do |
|
159
|
+
OpenapiFirst::Test.setup do |test|
|
159
160
|
test.register('openapi/openapi.yaml')
|
160
161
|
test.minimum_coverage = 100 # (Optional) Setting this will lead to an `exit 2` if coverage is below minimum
|
161
162
|
test.skip_response_coverage { it.status == '500' } # (Optional) Skip certain responses
|
@@ -168,7 +169,13 @@ Here is how to set it up with [rack-test](https://github.com/rack/rack-test):
|
|
168
169
|
OpenapiFirst::Test.app(MyApp)
|
169
170
|
end
|
170
171
|
```
|
171
|
-
3. Run your tests. The Coverage feature will tell you about missing request/responses.
|
172
|
+
3. Run your tests. The Coverage feature will tell you about missing request/responses.
|
173
|
+
|
174
|
+
Or you can generate a Module and include it in your rspec spec_helper.rb:
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
config.include OpenapiFirst::Test::Methods[MyApp], type: :request
|
178
|
+
```
|
172
179
|
|
173
180
|
(✷1): It does not matter what method of openapi_first you use to validate requests/responses. Instead of using `OpenapiFirstTest.app` to wrap your application, you could also use the middlewares or [test assertion method](#test-assertions), but you would have to do that for all requests/responses defined in your API description to make coverage work.
|
174
181
|
|
@@ -302,7 +309,7 @@ Setup globally:
|
|
302
309
|
```ruby
|
303
310
|
OpenapiFirst.configure do |config|
|
304
311
|
config.after_request_parameter_property_validation do |data, property, property_schema|
|
305
|
-
data[property] = Date.iso8601(data[property]) if
|
312
|
+
data[property] = Date.iso8601(data[property]) if property_schema['format'] == 'date'
|
306
313
|
end
|
307
314
|
end
|
308
315
|
```
|
@@ -318,9 +325,34 @@ That aside, closer integration with specific frameworks like Sinatra, Hanami, Ro
|
|
318
325
|
|
319
326
|
## Alternatives
|
320
327
|
|
321
|
-
This gem was inspired by [
|
328
|
+
This gem was inspired by [committee](https://github.com/interagent/committee) (Ruby) and [Connexion](https://github.com/spec-first/connexion) (Python).
|
322
329
|
Here is a [feature comparison between openapi_first and committee](https://gist.github.com/ahx/1538c31f0652f459861713b5259e366a).
|
323
330
|
|
331
|
+
## Frequently Asked Questions
|
332
|
+
|
333
|
+
### How can I adapt request paths that don't match my schema?
|
334
|
+
|
335
|
+
If your API is deployed at a different path than what's defined in your OpenAPI schema, you can use `env[OpenapiFirst::PATH]` to override the path used for schema matching.
|
336
|
+
|
337
|
+
Let's say you have `openapi.yaml` like this:
|
338
|
+
|
339
|
+
```yaml
|
340
|
+
servers:
|
341
|
+
- url: https://yourhost/api
|
342
|
+
paths:
|
343
|
+
# The actual endpoint URL is https://yourhost/api/resource
|
344
|
+
/resource:
|
345
|
+
```
|
346
|
+
|
347
|
+
Here your OpenAPI schema defines endpoints starting with `/resource` but your actual application is mounted at `/api/resource`. You can bridge the gap by transforming the path via the `path:` configuration:
|
348
|
+
|
349
|
+
```ruby
|
350
|
+
oad = OpenapiFirst.load('openapi.yaml') do |config|
|
351
|
+
config.path = ->(req) { request.path.delete_prefix('/api') }
|
352
|
+
end
|
353
|
+
use OpenapiFirst::Middlewares::RequestValidation, oad
|
354
|
+
```
|
355
|
+
|
324
356
|
## Development
|
325
357
|
|
326
358
|
Run `bin/setup` to install dependencies.
|
@@ -50,10 +50,8 @@ module OpenapiFirst
|
|
50
50
|
version = document['openapi']
|
51
51
|
case version
|
52
52
|
when /\A3\.1\.\d+\z/
|
53
|
-
@document_schema = JSONSchemer.openapi31_document
|
54
53
|
document.fetch('jsonSchemaDialect') { JSONSchemer::OpenAPI31::BASE_URI.to_s }
|
55
54
|
when /\A3\.0\.\d+\z/
|
56
|
-
@document_schema = JSONSchemer.openapi30_document
|
57
55
|
JSONSchemer::OpenAPI30::BASE_URI.to_s
|
58
56
|
else
|
59
57
|
raise Error, "Unsupported OpenAPI version #{version.inspect} #{filepath}"
|
@@ -15,10 +15,11 @@ module OpenapiFirst
|
|
15
15
|
@request_validation_raise_error = false
|
16
16
|
@response_validation_raise_error = true
|
17
17
|
@hooks = (HOOKS.map { [_1, Set.new] }).to_h
|
18
|
+
@path = nil
|
18
19
|
end
|
19
20
|
|
20
21
|
attr_reader :request_validation_error_response, :hooks
|
21
|
-
attr_accessor :request_validation_raise_error, :response_validation_raise_error
|
22
|
+
attr_accessor :request_validation_raise_error, :response_validation_raise_error, :path
|
22
23
|
|
23
24
|
def clone
|
24
25
|
copy = super
|
@@ -40,12 +40,30 @@ module OpenapiFirst
|
|
40
40
|
# @return [Enumerable[Router::Route]]
|
41
41
|
def_delegators :@router, :routes
|
42
42
|
|
43
|
+
# Returns a unique identifier for this API definition
|
44
|
+
# @return [String] A unique key for this API definition
|
45
|
+
def key
|
46
|
+
return filepath if filepath
|
47
|
+
|
48
|
+
info = self['info'] || {}
|
49
|
+
title = info['title']
|
50
|
+
version = info['version']
|
51
|
+
|
52
|
+
if title.nil? || version.nil?
|
53
|
+
raise ArgumentError,
|
54
|
+
"Cannot generate key for the OpenAPI document because 'info.title' or 'info.version' is missing. " \
|
55
|
+
'Please add these fields to your OpenAPI document.'
|
56
|
+
end
|
57
|
+
|
58
|
+
"#{title} @ #{version}"
|
59
|
+
end
|
60
|
+
|
43
61
|
# Validates the request against the API description.
|
44
62
|
# @param [Rack::Request] request The Rack request object.
|
45
63
|
# @param [Boolean] raise_error Whether to raise an error if validation fails.
|
46
64
|
# @return [ValidatedRequest] The validated request object.
|
47
65
|
def validate_request(request, raise_error: false)
|
48
|
-
route = @router.match(request.request_method, request
|
66
|
+
route = @router.match(request.request_method, resolve_path(request), content_type: request.content_type)
|
49
67
|
if route.error
|
50
68
|
ValidatedRequest.new(request, error: route.error)
|
51
69
|
else
|
@@ -62,7 +80,8 @@ module OpenapiFirst
|
|
62
80
|
# @param raise_error [Boolean] Whethir to raise an error if validation fails.
|
63
81
|
# @return [ValidatedResponse] The validated response object.
|
64
82
|
def validate_response(rack_request, rack_response, raise_error: false)
|
65
|
-
route = @router.match(rack_request.request_method, rack_request
|
83
|
+
route = @router.match(rack_request.request_method, resolve_path(rack_request),
|
84
|
+
content_type: rack_request.content_type)
|
66
85
|
return if route.error # Skip response validation for unknown requests
|
67
86
|
|
68
87
|
response_match = route.match_response(status: rack_response.status, content_type: rack_response.content_type)
|
@@ -76,5 +95,13 @@ module OpenapiFirst
|
|
76
95
|
raise validated.error.exception(validated) if raise_error && validated.invalid?
|
77
96
|
end
|
78
97
|
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def resolve_path(rack_request)
|
102
|
+
return rack_request.path unless @config.path
|
103
|
+
|
104
|
+
@config.path.call(rack_request)
|
105
|
+
end
|
79
106
|
end
|
80
107
|
end
|
@@ -13,7 +13,7 @@ module OpenapiFirst
|
|
13
13
|
class UnknownRequestError < StandardError; end
|
14
14
|
|
15
15
|
def self.for(oad, skip_response: nil)
|
16
|
-
plan = new(filepath: oad.filepath)
|
16
|
+
plan = new(definition_key: oad.key, filepath: oad.filepath)
|
17
17
|
oad.routes.each do |route|
|
18
18
|
responses = skip_response ? route.responses.reject(&skip_response) : route.responses
|
19
19
|
plan.add_route request_method: route.request_method,
|
@@ -24,13 +24,14 @@ module OpenapiFirst
|
|
24
24
|
plan
|
25
25
|
end
|
26
26
|
|
27
|
-
def initialize(filepath:)
|
27
|
+
def initialize(definition_key:, filepath: nil)
|
28
28
|
@routes = []
|
29
29
|
@index = {}
|
30
|
+
@api_identifier = filepath || definition_key
|
30
31
|
@filepath = filepath
|
31
32
|
end
|
32
33
|
|
33
|
-
attr_reader :filepath, :routes
|
34
|
+
attr_reader :api_identifier, :filepath, :routes
|
34
35
|
private attr_reader :index
|
35
36
|
|
36
37
|
def track_request(validated_request)
|
@@ -30,8 +30,7 @@ module OpenapiFirst
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def format_plan(plan)
|
33
|
-
|
34
|
-
puts ['', "API validation coverage for #{filepath}: #{plan.coverage}%"]
|
33
|
+
puts ['', "API validation coverage for #{plan.api_identifier}: #{plan.coverage}%"]
|
35
34
|
return if plan.done? && !verbose
|
36
35
|
|
37
36
|
plan.routes.each do |route|
|
@@ -36,7 +36,7 @@ module OpenapiFirst
|
|
36
36
|
def start(skip_response: nil)
|
37
37
|
@current_run = Test.definitions.values.to_h do |oad|
|
38
38
|
plan = Plan.for(oad, skip_response:)
|
39
|
-
[oad.
|
39
|
+
[oad.key, plan]
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -53,11 +53,11 @@ module OpenapiFirst
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def track_request(request, oad)
|
56
|
-
current_run[oad.
|
56
|
+
current_run[oad.key]&.track_request(request)
|
57
57
|
end
|
58
58
|
|
59
59
|
def track_response(response, _request, oad)
|
60
|
-
current_run[oad.
|
60
|
+
current_run[oad.key]&.track_response(response)
|
61
61
|
end
|
62
62
|
|
63
63
|
def result
|
@@ -7,21 +7,54 @@ module OpenapiFirst
|
|
7
7
|
module Test
|
8
8
|
# Methods to use in integration tests
|
9
9
|
module Methods
|
10
|
-
def self.
|
10
|
+
def self.included(base)
|
11
|
+
base.include(DefaultApiMethod)
|
12
|
+
base.include(AssertionMethod)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.[](application_under_test = nil, api: nil)
|
11
16
|
mod = Module.new do
|
12
17
|
def self.included(base)
|
13
|
-
OpenapiFirst::Test::Methods
|
18
|
+
base.include OpenapiFirst::Test::Methods::AssertionMethod
|
14
19
|
end
|
15
20
|
end
|
16
|
-
|
21
|
+
|
22
|
+
if api
|
23
|
+
mod.define_method(:openapi_first_default_api) { api }
|
24
|
+
else
|
25
|
+
mod.include(DefaultApiMethod)
|
26
|
+
end
|
27
|
+
|
28
|
+
if application_under_test
|
29
|
+
mod.define_method(:app) { OpenapiFirst::Test.app(application_under_test, api: openapi_first_default_api) }
|
30
|
+
end
|
31
|
+
|
17
32
|
mod
|
18
33
|
end
|
19
34
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
35
|
+
# Default methods
|
36
|
+
module DefaultApiMethod
|
37
|
+
# This is the default api that is used by assert_api_conform
|
38
|
+
# :default is the default name that is used if you don't pass an `api:` option to `OpenapiFirst::Test.register`
|
39
|
+
# This is overwritten if you pass an `api:` option to `include OpenapiFirst::Test::Methods[…]`
|
40
|
+
def openapi_first_default_api
|
41
|
+
klass = self.class
|
42
|
+
if klass.respond_to?(:metadata) && klass.metadata[:api]
|
43
|
+
klass.metadata[:api]
|
44
|
+
else
|
45
|
+
:default
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# @visibility private
|
51
|
+
module AssertionMethod
|
52
|
+
def self.included(base)
|
53
|
+
if Test.minitest?(base)
|
54
|
+
base.include(OpenapiFirst::Test::MinitestHelpers)
|
55
|
+
else
|
56
|
+
base.include(OpenapiFirst::Test::PlainHelpers)
|
57
|
+
end
|
25
58
|
end
|
26
59
|
end
|
27
60
|
end
|
@@ -5,7 +5,7 @@ module OpenapiFirst
|
|
5
5
|
# Assertion methods for Minitest
|
6
6
|
module MinitestHelpers
|
7
7
|
# :nocov:
|
8
|
-
def assert_api_conform(status: nil, api:
|
8
|
+
def assert_api_conform(status: nil, api: openapi_first_default_api)
|
9
9
|
api = OpenapiFirst::Test[api]
|
10
10
|
request = respond_to?(:last_request) ? last_request : @request
|
11
11
|
response = respond_to?(:last_response) ? last_response : @response
|
@@ -5,7 +5,7 @@ module OpenapiFirst
|
|
5
5
|
# Assertion methods to use when no known test framework was found
|
6
6
|
# These methods just raise an exception if an error was found
|
7
7
|
module PlainHelpers
|
8
|
-
def assert_api_conform(status: nil, api:
|
8
|
+
def assert_api_conform(status: nil, api: openapi_first_default_api)
|
9
9
|
api = OpenapiFirst::Test[api]
|
10
10
|
# :nocov:
|
11
11
|
request = respond_to?(:last_request) ? last_request : @request
|
data/lib/openapi_first/test.rb
CHANGED
@@ -22,8 +22,8 @@ module OpenapiFirst
|
|
22
22
|
yield self
|
23
23
|
end
|
24
24
|
|
25
|
-
def register(
|
26
|
-
Test.register(
|
25
|
+
def register(oad, as: :default)
|
26
|
+
Test.register(oad, as:)
|
27
27
|
end
|
28
28
|
|
29
29
|
attr_accessor :minimum_coverage, :coverage_formatter_options, :coverage_formatter
|
@@ -47,7 +47,7 @@ module OpenapiFirst
|
|
47
47
|
end
|
48
48
|
return unless minimum_coverage > coverage
|
49
49
|
|
50
|
-
puts "API Coverage fails with exit 2, because API coverage of #{coverage}%" \
|
50
|
+
puts "API Coverage fails with exit 2, because API coverage of #{coverage}% " \
|
51
51
|
"is below minimum of #{minimum_coverage}%!"
|
52
52
|
exit 2
|
53
53
|
# :nocov:
|
@@ -103,18 +103,23 @@ module OpenapiFirst
|
|
103
103
|
class << self
|
104
104
|
attr_reader :definitions
|
105
105
|
|
106
|
-
|
107
|
-
|
106
|
+
# Register an OpenAPI definition for testing
|
107
|
+
# @param path_or_definition [String, Definition] Path to the OpenAPI file or a Definition object
|
108
|
+
# @param as [Symbol] Name to register the API definition as
|
109
|
+
def register(path_or_definition, as: :default)
|
110
|
+
if definitions.key?(as) && as == :default
|
108
111
|
raise(
|
109
112
|
AlreadyRegisteredError,
|
110
113
|
"#{definitions[as].filepath.inspect} is already registered " \
|
111
|
-
"as ':default' so you cannot register #{
|
114
|
+
"as ':default' so you cannot register #{path_or_definition.inspect} without " \
|
112
115
|
'giving it a custom name. Please call register with a custom key like: ' \
|
113
|
-
"OpenapiFirst::Test.register(#{
|
116
|
+
"OpenapiFirst::Test.register(#{path_or_definition.inspect}, as: :my_other_api)"
|
114
117
|
)
|
115
118
|
end
|
116
119
|
|
117
|
-
|
120
|
+
definition = OpenapiFirst.load(path_or_definition)
|
121
|
+
definitions[as] = definition
|
122
|
+
definition
|
118
123
|
end
|
119
124
|
|
120
125
|
def [](api)
|
data/lib/openapi_first.rb
CHANGED
@@ -15,6 +15,10 @@ module OpenapiFirst
|
|
15
15
|
|
16
16
|
# Key in rack to find instance of Request
|
17
17
|
REQUEST = 'openapi.request'
|
18
|
+
|
19
|
+
# Key in rack to store the alternate path used for schema matching
|
20
|
+
PATH = 'openapi.path'
|
21
|
+
|
18
22
|
FAILURE = :openapi_first_validation_failure
|
19
23
|
|
20
24
|
# @return [Configuration]
|
@@ -48,9 +52,13 @@ module OpenapiFirst
|
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
51
|
-
# Load and dereference an OpenAPI spec file
|
55
|
+
# Load and dereference an OpenAPI spec file or return the Definition if it's already loaded
|
56
|
+
# @param filepath_or_definition [String, Definition] The path to the file or a Definition object
|
52
57
|
# @return [Definition]
|
53
|
-
def self.load(
|
58
|
+
def self.load(filepath_or_definition, only: nil, &)
|
59
|
+
return filepath_or_definition if filepath_or_definition.is_a?(Definition)
|
60
|
+
|
61
|
+
filepath = filepath_or_definition
|
54
62
|
raise FileNotFoundError, "File not found: #{filepath}" unless File.exist?(filepath)
|
55
63
|
|
56
64
|
contents = FileLoader.load(filepath)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openapi_first
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Haller
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-04
|
10
|
+
date: 2025-05-04 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: hana
|