openapi-ruby 3.2.0 → 3.4.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/README.md +62 -19
- data/lib/openapi_ruby/components/base.rb +10 -0
- data/lib/openapi_ruby/dsl/context.rb +6 -0
- data/lib/openapi_ruby/dsl/operation_context.rb +6 -0
- data/lib/openapi_ruby/dsl/response_context.rb +6 -0
- data/lib/openapi_ruby/generator/rake_task_support.rb +89 -0
- data/lib/openapi_ruby/version.rb +1 -1
- data/lib/openapi_ruby.rb +1 -0
- data/lib/tasks/openapi_ruby.rake +6 -40
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b58ff6e6c8ccbf7c8c02d01f6a79ea02717cf3c709de9d1c8a8f870bb44a84fb
|
|
4
|
+
data.tar.gz: e18b82cac3cd08bee2fcbee279d45e9b705b62ad0015feb8e3e5408cf4af63a5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d9248a97e6b5f513516f5d97d87ef81f68047ce4db54c62503667d20751bf15f99fb4644cde3369d017b388184e92e65f904aa171e546c189134d8d1dc742eea
|
|
7
|
+
data.tar.gz: 4a627ed1b9bc867c24263627a27f01f22d5fc50bfde5ffe9d93e87484c50e68f61e739162c198c808b979d484c9c1a3b80921c14eedd32a9c7b076a702a90cb9
|
data/README.md
CHANGED
|
@@ -193,6 +193,31 @@ class Schemas::AdminUser
|
|
|
193
193
|
end
|
|
194
194
|
```
|
|
195
195
|
|
|
196
|
+
### Class References
|
|
197
|
+
|
|
198
|
+
Instead of writing `$ref` strings manually, you can pass component classes directly anywhere a `$ref` is expected. This gives you typo protection (via `NameError`), IDE navigation, and less boilerplate:
|
|
199
|
+
|
|
200
|
+
```ruby
|
|
201
|
+
# Instead of:
|
|
202
|
+
schema "$ref" => "#/components/schemas/User"
|
|
203
|
+
schema type: :array, items: { "$ref" => "#/components/schemas/User" }
|
|
204
|
+
|
|
205
|
+
# You can write:
|
|
206
|
+
schema Schemas::User
|
|
207
|
+
schema type: :array, items: Schemas::User
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
This works in `schema`, `request_body`, and anywhere nested inside hash/array definitions. Non-component classes raise `ArgumentError`.
|
|
211
|
+
|
|
212
|
+
You can also use the explicit `.to_ref` method:
|
|
213
|
+
|
|
214
|
+
```ruby
|
|
215
|
+
Schemas::User.to_ref
|
|
216
|
+
# => { "$ref" => "#/components/schemas/User" }
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Both class refs and string `$ref` hashes are fully supported — use whichever you prefer.
|
|
220
|
+
|
|
196
221
|
### Strong Params
|
|
197
222
|
|
|
198
223
|
Schema components can derive Rails strong params permit lists:
|
|
@@ -252,7 +277,7 @@ RSpec.describe "Users API", type: :openapi do
|
|
|
252
277
|
produces "application/json"
|
|
253
278
|
|
|
254
279
|
response 200, "returns all users" do
|
|
255
|
-
schema type: :array, items:
|
|
280
|
+
schema type: :array, items: Schemas::User
|
|
256
281
|
|
|
257
282
|
run_test! do
|
|
258
283
|
expect(JSON.parse(response.body).length).to be > 0
|
|
@@ -265,19 +290,17 @@ RSpec.describe "Users API", type: :openapi do
|
|
|
265
290
|
consumes "application/json"
|
|
266
291
|
|
|
267
292
|
request_body required: true, content: {
|
|
268
|
-
"application/json" => {
|
|
269
|
-
schema: { "$ref" => "#/components/schemas/UserInput" }
|
|
270
|
-
}
|
|
293
|
+
"application/json" => { schema: Schemas::UserInput }
|
|
271
294
|
}
|
|
272
295
|
|
|
273
296
|
response 201, "user created" do
|
|
274
|
-
schema
|
|
297
|
+
schema Schemas::User
|
|
275
298
|
let(:request_body) { { name: "Jane", email: "jane@example.com" } }
|
|
276
299
|
run_test!
|
|
277
300
|
end
|
|
278
301
|
|
|
279
302
|
response 422, "validation errors" do
|
|
280
|
-
schema
|
|
303
|
+
schema Schemas::ValidationErrors
|
|
281
304
|
let(:request_body) { { name: "" } }
|
|
282
305
|
run_test!
|
|
283
306
|
end
|
|
@@ -289,7 +312,7 @@ RSpec.describe "Users API", type: :openapi do
|
|
|
289
312
|
|
|
290
313
|
get "Get a user" do
|
|
291
314
|
response 200, "user found" do
|
|
292
|
-
schema
|
|
315
|
+
schema Schemas::User
|
|
293
316
|
let(:id) { User.create!(name: "Jane", email: "jane@example.com").id }
|
|
294
317
|
run_test!
|
|
295
318
|
end
|
|
@@ -319,7 +342,7 @@ RSpec.describe "Users API", type: :openapi do
|
|
|
319
342
|
produces "application/json"
|
|
320
343
|
|
|
321
344
|
response 200, "returns all users" do
|
|
322
|
-
schema type: :array, items:
|
|
345
|
+
schema type: :array, items: Schemas::User
|
|
323
346
|
end
|
|
324
347
|
end
|
|
325
348
|
|
|
@@ -327,17 +350,15 @@ RSpec.describe "Users API", type: :openapi do
|
|
|
327
350
|
consumes "application/json"
|
|
328
351
|
|
|
329
352
|
request_body required: true, content: {
|
|
330
|
-
"application/json" => {
|
|
331
|
-
schema: { "$ref" => "#/components/schemas/UserInput" }
|
|
332
|
-
}
|
|
353
|
+
"application/json" => { schema: Schemas::UserInput }
|
|
333
354
|
}
|
|
334
355
|
|
|
335
356
|
response 201, "user created" do
|
|
336
|
-
schema
|
|
357
|
+
schema Schemas::User
|
|
337
358
|
end
|
|
338
359
|
|
|
339
360
|
response 422, "validation errors" do
|
|
340
|
-
schema
|
|
361
|
+
schema Schemas::ValidationErrors
|
|
341
362
|
end
|
|
342
363
|
end
|
|
343
364
|
end
|
|
@@ -407,7 +428,7 @@ class UsersApiTest < ActionDispatch::IntegrationTest
|
|
|
407
428
|
produces "application/json"
|
|
408
429
|
|
|
409
430
|
response 200, "returns all users" do
|
|
410
|
-
schema type: :array, items:
|
|
431
|
+
schema type: :array, items: Schemas::User
|
|
411
432
|
end
|
|
412
433
|
end
|
|
413
434
|
|
|
@@ -415,13 +436,11 @@ class UsersApiTest < ActionDispatch::IntegrationTest
|
|
|
415
436
|
consumes "application/json"
|
|
416
437
|
|
|
417
438
|
request_body required: true, content: {
|
|
418
|
-
"application/json" => {
|
|
419
|
-
schema: { "$ref" => "#/components/schemas/UserInput" }
|
|
420
|
-
}
|
|
439
|
+
"application/json" => { schema: Schemas::UserInput }
|
|
421
440
|
}
|
|
422
441
|
|
|
423
442
|
response 201, "user created" do
|
|
424
|
-
schema
|
|
443
|
+
schema Schemas::User
|
|
425
444
|
end
|
|
426
445
|
end
|
|
427
446
|
end
|
|
@@ -450,10 +469,34 @@ Generate OpenAPI spec files without running tests:
|
|
|
450
469
|
rake openapi_ruby:generate
|
|
451
470
|
```
|
|
452
471
|
|
|
453
|
-
This loads spec/test files to collect API definitions and writes schemas without running any tests. It auto-detects the test framework, or you can set `FRAMEWORK=rspec` or `FRAMEWORK=
|
|
472
|
+
This loads spec/test files to collect API definitions and writes schemas without running any tests. It auto-detects the test framework, or you can set `FRAMEWORK=rspec`, `FRAMEWORK=minitest`, or `FRAMEWORK=hybrid`. Custom patterns: `PATTERN="packs/*/spec/**/*_spec.rb"`.
|
|
454
473
|
|
|
455
474
|
Schemas are **only** written by the rake task — running tests (`bundle exec rspec`, `rails test`) does not generate or overwrite schema files. This prevents partial schema overwrites when running a subset of specs.
|
|
456
475
|
|
|
476
|
+
### Migrating from RSpec to Minitest (or vice versa)
|
|
477
|
+
|
|
478
|
+
When both `spec/spec_helper.rb` and `test/test_helper.rb` are present, the rake task auto-selects `FRAMEWORK=hybrid` — it requires both adapters and loads both glob patterns (`spec/**/*_spec.rb,test/**/*_test.rb`) into one process. Style 1 `path(...)` and Style 2 `api_path(...)` definitions register into the same `MetadataStore`, so a single schema file holds paths contributed by either DSL.
|
|
479
|
+
|
|
480
|
+
Two things to set up on the consumer side so the two test frameworks don't both wire themselves into Rails' lazy-load hooks during schema generation:
|
|
481
|
+
|
|
482
|
+
```ruby
|
|
483
|
+
# test/test_helper.rb
|
|
484
|
+
unless ENV["OPENAPI_RUBY_GENERATING"]
|
|
485
|
+
require "rails/test_help"
|
|
486
|
+
# ...other test-time setup...
|
|
487
|
+
end
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
```ruby
|
|
491
|
+
# spec/rails_helper.rb
|
|
492
|
+
unless ENV["OPENAPI_RUBY_GENERATING"]
|
|
493
|
+
require "rspec/rails"
|
|
494
|
+
# ...other spec-time setup...
|
|
495
|
+
end
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
The rake task sets `OPENAPI_RUBY_GENERATING=true` in the subprocess. With the guards in place, neither test framework boots its full Rails integration during generation — only the DSL needs to be live for `api_path` / `path` to register.
|
|
499
|
+
|
|
457
500
|
## Runtime Middleware
|
|
458
501
|
|
|
459
502
|
Validate requests and responses against your OpenAPI spec at runtime:
|
|
@@ -85,6 +85,10 @@ module OpenapiRuby
|
|
|
85
85
|
end
|
|
86
86
|
end
|
|
87
87
|
|
|
88
|
+
def to_ref
|
|
89
|
+
OpenapiRuby::Core::RefResolver.ref_object(_component_type, component_name)
|
|
90
|
+
end
|
|
91
|
+
|
|
88
92
|
def to_openapi
|
|
89
93
|
definition = _schema_definition.deep_dup
|
|
90
94
|
|
|
@@ -147,6 +151,12 @@ module OpenapiRuby
|
|
|
147
151
|
|
|
148
152
|
def deep_stringify(value)
|
|
149
153
|
case value
|
|
154
|
+
when Class
|
|
155
|
+
if value < OpenapiRuby::Components::Base
|
|
156
|
+
value.to_ref
|
|
157
|
+
else
|
|
158
|
+
raise ArgumentError, "#{value} is not an OpenapiRuby component"
|
|
159
|
+
end
|
|
150
160
|
when Hash
|
|
151
161
|
value.each_with_object({}) { |(k, v), h| h[k.to_s] = deep_stringify(v) }
|
|
152
162
|
when Array
|
|
@@ -45,6 +45,12 @@ module OpenapiRuby
|
|
|
45
45
|
|
|
46
46
|
def deep_stringify(value)
|
|
47
47
|
case value
|
|
48
|
+
when Class
|
|
49
|
+
if value < OpenapiRuby::Components::Base
|
|
50
|
+
value.to_ref
|
|
51
|
+
else
|
|
52
|
+
raise ArgumentError, "#{value} is not an OpenapiRuby component"
|
|
53
|
+
end
|
|
48
54
|
when Hash
|
|
49
55
|
value.each_with_object({}) { |(k, v), h| h[k.to_s] = deep_stringify(v) }
|
|
50
56
|
when Array
|
|
@@ -128,6 +128,12 @@ module OpenapiRuby
|
|
|
128
128
|
|
|
129
129
|
def deep_stringify(value)
|
|
130
130
|
case value
|
|
131
|
+
when Class
|
|
132
|
+
if value < OpenapiRuby::Components::Base
|
|
133
|
+
value.to_ref
|
|
134
|
+
else
|
|
135
|
+
raise ArgumentError, "#{value} is not an OpenapiRuby component"
|
|
136
|
+
end
|
|
131
137
|
when Hash
|
|
132
138
|
value.each_with_object({}) { |(k, v), h| h[k.to_s] = deep_stringify(v) }
|
|
133
139
|
when Array
|
|
@@ -72,6 +72,12 @@ module OpenapiRuby
|
|
|
72
72
|
|
|
73
73
|
def deep_stringify(value)
|
|
74
74
|
case value
|
|
75
|
+
when Class
|
|
76
|
+
if value < OpenapiRuby::Components::Base
|
|
77
|
+
value.to_ref
|
|
78
|
+
else
|
|
79
|
+
raise ArgumentError, "#{value} is not an OpenapiRuby component"
|
|
80
|
+
end
|
|
75
81
|
when Hash
|
|
76
82
|
value.each_with_object({}) { |(k, v), h| h[k.to_s] = deep_stringify(v) }
|
|
77
83
|
when Array
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenapiRuby
|
|
4
|
+
module Generator
|
|
5
|
+
# Helpers backing the `openapi_ruby:generate` rake task. Extracted
|
|
6
|
+
# so the framework detection / script generation logic is testable
|
|
7
|
+
# without booting Rake.
|
|
8
|
+
module RakeTaskSupport
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
def detect_test_framework
|
|
12
|
+
rspec = File.exist?("spec/spec_helper.rb") || File.exist?("spec/rails_helper.rb")
|
|
13
|
+
minitest = File.exist?("test/test_helper.rb")
|
|
14
|
+
|
|
15
|
+
if rspec && minitest
|
|
16
|
+
"hybrid"
|
|
17
|
+
elsif rspec
|
|
18
|
+
"rspec"
|
|
19
|
+
elsif minitest
|
|
20
|
+
"minitest"
|
|
21
|
+
else
|
|
22
|
+
raise ArgumentError,
|
|
23
|
+
"Could not detect test framework. Set FRAMEWORK=rspec, FRAMEWORK=minitest, or FRAMEWORK=hybrid."
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def default_pattern_for(framework)
|
|
28
|
+
case framework
|
|
29
|
+
when "rspec" then "spec/**/*_spec.rb"
|
|
30
|
+
when "minitest" then "test/**/*_test.rb"
|
|
31
|
+
when "hybrid" then "spec/**/*_spec.rb,test/**/*_test.rb"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def generate_script(framework, pattern)
|
|
36
|
+
case framework
|
|
37
|
+
when "rspec" then rspec_script(pattern)
|
|
38
|
+
when "minitest" then minitest_script(pattern)
|
|
39
|
+
when "hybrid" then hybrid_script(pattern)
|
|
40
|
+
else
|
|
41
|
+
raise ArgumentError, "Unknown test framework '#{framework}'."
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def rspec_script(pattern)
|
|
46
|
+
<<~RUBY
|
|
47
|
+
require "rspec/core"
|
|
48
|
+
$LOAD_PATH.unshift(File.expand_path("spec")) unless $LOAD_PATH.include?(File.expand_path("spec"))
|
|
49
|
+
#{glob_loads(pattern)}
|
|
50
|
+
OpenapiRuby::Generator::SchemaWriter.generate_all!
|
|
51
|
+
RUBY
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def minitest_script(pattern)
|
|
55
|
+
<<~RUBY
|
|
56
|
+
require "openapi_ruby/minitest"
|
|
57
|
+
#{glob_loads(pattern)}
|
|
58
|
+
OpenapiRuby::Generator::SchemaWriter.generate_all!
|
|
59
|
+
RUBY
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Loads both adapters and both file globs in one process. Useful
|
|
63
|
+
# during a phased RSpec → Minitest migration where the suite
|
|
64
|
+
# holds both DSL styles. Consumers should guard
|
|
65
|
+
# `require "rails/test_help"` and `require "rspec/rails"` in
|
|
66
|
+
# their test helpers with `unless ENV["OPENAPI_RUBY_GENERATING"]`
|
|
67
|
+
# so the two test frameworks don't both register Rails lazy
|
|
68
|
+
# hooks in the same process — only the DSL needs to be live for
|
|
69
|
+
# schema generation.
|
|
70
|
+
def hybrid_script(pattern)
|
|
71
|
+
<<~RUBY
|
|
72
|
+
require "rspec/core"
|
|
73
|
+
require "openapi_ruby/rspec"
|
|
74
|
+
require "openapi_ruby/minitest"
|
|
75
|
+
$LOAD_PATH.unshift(File.expand_path("spec")) unless $LOAD_PATH.include?(File.expand_path("spec"))
|
|
76
|
+
$LOAD_PATH.unshift(File.expand_path("test")) unless $LOAD_PATH.include?(File.expand_path("test"))
|
|
77
|
+
#{glob_loads(pattern)}
|
|
78
|
+
OpenapiRuby::Generator::SchemaWriter.generate_all!
|
|
79
|
+
RUBY
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def glob_loads(pattern)
|
|
83
|
+
pattern.split(",").map do |p|
|
|
84
|
+
%[Dir.glob(#{p.strip.inspect}).sort.each { |f| require File.expand_path(f) }]
|
|
85
|
+
end.join("\n")
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
data/lib/openapi_ruby/version.rb
CHANGED
data/lib/openapi_ruby.rb
CHANGED
|
@@ -47,6 +47,7 @@ require_relative "openapi_ruby/testing/request_validator"
|
|
|
47
47
|
require_relative "openapi_ruby/testing/assertions"
|
|
48
48
|
require_relative "openapi_ruby/testing/coverage"
|
|
49
49
|
require_relative "openapi_ruby/generator/schema_writer"
|
|
50
|
+
require_relative "openapi_ruby/generator/rake_task_support"
|
|
50
51
|
require_relative "openapi_ruby/middleware/path_matcher"
|
|
51
52
|
require_relative "openapi_ruby/middleware/coercion"
|
|
52
53
|
require_relative "openapi_ruby/middleware/error_handler"
|
data/lib/tasks/openapi_ruby.rake
CHANGED
|
@@ -1,55 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "openapi_ruby/generator/rake_task_support"
|
|
4
|
+
|
|
3
5
|
namespace :openapi_ruby do
|
|
4
6
|
desc "Generate OpenAPI schema files from spec definitions and components"
|
|
5
7
|
task :generate do
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
support = OpenapiRuby::Generator::RakeTaskSupport
|
|
9
|
+
framework = ENV.fetch("FRAMEWORK") { support.detect_test_framework }.to_s
|
|
10
|
+
pattern = ENV.fetch("PATTERN") { support.default_pattern_for(framework) }
|
|
8
11
|
|
|
9
12
|
# Spawn a subprocess so RAILS_ENV defaults to "test" cleanly,
|
|
10
13
|
# just like rswag did with RSpec::Core::RakeTask.
|
|
11
14
|
env = {"RAILS_ENV" => ENV.fetch("RAILS_ENV", "test"), "OPENAPI_RUBY_GENERATING" => "true"}
|
|
12
|
-
script = generate_script(framework, pattern)
|
|
15
|
+
script = support.generate_script(framework, pattern)
|
|
13
16
|
command = "bundle exec ruby -e #{Shellwords.escape(script)}"
|
|
14
17
|
|
|
15
18
|
puts "Generating OpenAPI schemas (#{framework})..."
|
|
16
19
|
system(env, command) || abort("Schema generation failed")
|
|
17
20
|
end
|
|
18
21
|
end
|
|
19
|
-
|
|
20
|
-
def detect_test_framework
|
|
21
|
-
if File.exist?("spec/spec_helper.rb") || File.exist?("spec/rails_helper.rb")
|
|
22
|
-
"rspec"
|
|
23
|
-
elsif File.exist?("test/test_helper.rb")
|
|
24
|
-
"minitest"
|
|
25
|
-
else
|
|
26
|
-
abort "Could not detect test framework. Set FRAMEWORK=rspec or FRAMEWORK=minitest."
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def default_pattern_for(framework)
|
|
31
|
-
case framework
|
|
32
|
-
when "rspec" then "spec/**/*_spec.rb"
|
|
33
|
-
when "minitest" then "test/**/*_test.rb"
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def generate_script(framework, pattern)
|
|
38
|
-
case framework
|
|
39
|
-
when "rspec"
|
|
40
|
-
<<~RUBY
|
|
41
|
-
require "rspec/core"
|
|
42
|
-
$LOAD_PATH.unshift(File.expand_path("spec")) unless $LOAD_PATH.include?(File.expand_path("spec"))
|
|
43
|
-
#{pattern.split(",").map { |p| %[Dir.glob(#{p.strip.inspect}).sort.each { |f| require File.expand_path(f) }] }.join("\n")}
|
|
44
|
-
OpenapiRuby::Generator::SchemaWriter.generate_all!
|
|
45
|
-
RUBY
|
|
46
|
-
when "minitest"
|
|
47
|
-
<<~RUBY
|
|
48
|
-
require "openapi_ruby/minitest"
|
|
49
|
-
#{pattern.split(",").map { |p| %[Dir.glob(#{p.strip.inspect}).sort.each { |f| require File.expand_path(f) }] }.join("\n")}
|
|
50
|
-
OpenapiRuby::Generator::SchemaWriter.generate_all!
|
|
51
|
-
RUBY
|
|
52
|
-
else
|
|
53
|
-
abort "Unknown test framework '#{framework}'."
|
|
54
|
-
end
|
|
55
|
-
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openapi-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Morten Hartvig
|
|
@@ -105,6 +105,7 @@ files:
|
|
|
105
105
|
- lib/openapi_ruby/dsl/response_context.rb
|
|
106
106
|
- lib/openapi_ruby/engine.rb
|
|
107
107
|
- lib/openapi_ruby/errors.rb
|
|
108
|
+
- lib/openapi_ruby/generator/rake_task_support.rb
|
|
108
109
|
- lib/openapi_ruby/generator/schema_writer.rb
|
|
109
110
|
- lib/openapi_ruby/middleware/coercion.rb
|
|
110
111
|
- lib/openapi_ruby/middleware/error_handler.rb
|