openapi-ruby 4.0.3 → 4.2.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 +277 -10
- data/Rakefile +32 -0
- data/app/controllers/openapi_ruby/schemas_controller.rb +4 -45
- data/app/controllers/openapi_ruby/ui_controller.rb +11 -68
- data/lib/openapi_ruby/adapters/context_resolution.rb +113 -0
- data/lib/openapi_ruby/adapters/minitest.rb +54 -20
- data/lib/openapi_ruby/adapters/rspec.rb +58 -28
- data/lib/openapi_ruby/components/loader.rb +15 -0
- data/lib/openapi_ruby/configuration.rb +20 -1
- data/lib/openapi_ruby/engine.rb +1 -38
- data/lib/openapi_ruby/errors.rb +7 -0
- data/lib/openapi_ruby/generator/rake_task_support.rb +43 -1
- data/lib/openapi_ruby/hanami.rb +69 -0
- data/lib/openapi_ruby/host.rb +53 -0
- data/lib/openapi_ruby/middleware/installer.rb +50 -0
- data/lib/openapi_ruby/rack_app.rb +94 -0
- data/lib/openapi_ruby/rake_tasks.rb +39 -0
- data/lib/openapi_ruby/serving.rb +135 -0
- data/lib/openapi_ruby/testing/transport.rb +99 -0
- data/lib/openapi_ruby/version.rb +1 -1
- data/lib/openapi_ruby.rb +5 -0
- data/lib/tasks/openapi_ruby.rake +1 -19
- metadata +14 -20
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenapiRuby
|
|
4
|
+
module Middleware
|
|
5
|
+
# Installs the runtime validation middleware onto a Rack stack. Anything
|
|
6
|
+
# responding to #use works — Rails' `app.middleware` and Hanami's
|
|
7
|
+
# `config.middleware` share that much API, so no host branching is needed.
|
|
8
|
+
module Installer
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
def install!(stack, root: OpenapiRuby.app_root)
|
|
12
|
+
config = OpenapiRuby.configuration
|
|
13
|
+
|
|
14
|
+
return if ENV["OPENAPI_RUBY_GENERATING"]
|
|
15
|
+
return if config.request_validation == :disabled && config.response_validation == :disabled
|
|
16
|
+
|
|
17
|
+
config.schemas.each do |name, schema_config|
|
|
18
|
+
schema_path = resolve_schema_path(config, name, root)
|
|
19
|
+
next unless schema_path && File.exist?(schema_path)
|
|
20
|
+
|
|
21
|
+
resolver = SchemaResolver.new(
|
|
22
|
+
spec_path: schema_path,
|
|
23
|
+
strict_reference_validation: config.strict_reference_validation
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
prefix = schema_config[:prefix]
|
|
27
|
+
|
|
28
|
+
if config.request_validation != :disabled
|
|
29
|
+
stack.use RequestValidation,
|
|
30
|
+
schema_resolver: resolver,
|
|
31
|
+
mode: config.request_validation,
|
|
32
|
+
prefix: prefix
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
if config.response_validation != :disabled
|
|
36
|
+
stack.use ResponseValidation,
|
|
37
|
+
schema_resolver: resolver,
|
|
38
|
+
mode: config.response_validation,
|
|
39
|
+
prefix: prefix
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def resolve_schema_path(config, schema_name, root)
|
|
45
|
+
ext = (config.schema_output_format == :json) ? "json" : "yaml"
|
|
46
|
+
File.join(root.to_s, config.schema_output_dir, "#{schema_name}.#{ext}")
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rack"
|
|
4
|
+
|
|
5
|
+
module OpenapiRuby
|
|
6
|
+
# Serves the generated schema documents and the Swagger UI as a plain Rack
|
|
7
|
+
# app, for hosts with no engine to mount:
|
|
8
|
+
#
|
|
9
|
+
# # Hanami — config/routes.rb
|
|
10
|
+
# mount OpenapiRuby::RackApp, at: "/api-docs"
|
|
11
|
+
#
|
|
12
|
+
# Routes mirror the Rails engine's (config/routes.rb) so both hosts expose
|
|
13
|
+
# the same paths. Schema URLs are derived from SCRIPT_NAME, so the app works
|
|
14
|
+
# at any mount point.
|
|
15
|
+
#
|
|
16
|
+
# Deliberately not namespaced under OpenapiRuby::Rack: that constant would
|
|
17
|
+
# shadow the top-level ::Rack for every file in this gem.
|
|
18
|
+
class RackApp
|
|
19
|
+
SCHEMA_PATH = %r{\A/schemas/(?<name>.+)\z}
|
|
20
|
+
SCHEMA_EXTENSION = /\.(json|ya?ml)\z/
|
|
21
|
+
|
|
22
|
+
def self.call(env)
|
|
23
|
+
(@app ||= new).call(env)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def call(env)
|
|
27
|
+
request = ::Rack::Request.new(env)
|
|
28
|
+
return method_not_allowed unless request.get? || request.head?
|
|
29
|
+
|
|
30
|
+
status, headers, body = case request.path_info
|
|
31
|
+
when "", "/" then ui(request)
|
|
32
|
+
when "/schemas" then schema_index
|
|
33
|
+
when "/oauth2-redirect.html" then oauth2_redirect
|
|
34
|
+
when SCHEMA_PATH then schema(::Regexp.last_match(:name), request)
|
|
35
|
+
else not_found
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Drop the body ourselves: Rails runs Rack::Head above the engine, a bare
|
|
39
|
+
# Hanami mount has nothing between the router and here.
|
|
40
|
+
[status, headers, request.head? ? [] : body]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def ui(request)
|
|
46
|
+
return not_found unless OpenapiRuby.configuration.ui_enabled
|
|
47
|
+
|
|
48
|
+
html = Serving.swagger_ui_html(
|
|
49
|
+
schema_urls: schema_urls(request),
|
|
50
|
+
ui_config: OpenapiRuby.configuration.ui_config
|
|
51
|
+
)
|
|
52
|
+
respond(200, "text/html", html)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def oauth2_redirect
|
|
56
|
+
return not_found unless OpenapiRuby.configuration.ui_enabled
|
|
57
|
+
|
|
58
|
+
respond(200, "text/html", File.read(Serving.oauth2_redirect_file))
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def schema_index
|
|
62
|
+
respond(200, "application/json", {schemas: Serving.schema_names}.to_json)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def schema(name, request)
|
|
66
|
+
document = Serving.schema_document(name.sub(SCHEMA_EXTENSION, ""), request: request)
|
|
67
|
+
return not_found unless document
|
|
68
|
+
|
|
69
|
+
content, content_type = document
|
|
70
|
+
respond(200, content_type, content)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def schema_urls(request)
|
|
74
|
+
OpenapiRuby.configuration.schemas.map do |name, schema_config|
|
|
75
|
+
{
|
|
76
|
+
url: "#{request.script_name}/schemas/#{name}.#{Serving.schema_format}",
|
|
77
|
+
name: schema_config.dig(:info, :title) || name.to_s
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def respond(status, content_type, body, headers = {})
|
|
83
|
+
[status, {"content-type" => content_type}.merge(headers), [body]]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def not_found
|
|
87
|
+
respond(404, "application/json", {error: "Not found"}.to_json)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def method_not_allowed
|
|
91
|
+
respond(405, "application/json", {error: "Method not allowed"}.to_json, "allow" => "GET, HEAD")
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rake"
|
|
4
|
+
require "shellwords"
|
|
5
|
+
require "openapi_ruby/generator/rake_task_support"
|
|
6
|
+
|
|
7
|
+
module OpenapiRuby
|
|
8
|
+
# The Rails engine picks up lib/tasks/*.rake on its own; other hosts add
|
|
9
|
+
#
|
|
10
|
+
# require "openapi_ruby/rake_tasks"
|
|
11
|
+
#
|
|
12
|
+
# to their Rakefile. Both routes end up here, so the task is defined once.
|
|
13
|
+
module RakeTasks
|
|
14
|
+
extend Rake::DSL
|
|
15
|
+
|
|
16
|
+
def self.install!
|
|
17
|
+
return if Rake::Task.task_defined?("openapi_ruby:generate")
|
|
18
|
+
|
|
19
|
+
namespace :openapi_ruby do
|
|
20
|
+
desc "Generate OpenAPI schema files from spec definitions and components"
|
|
21
|
+
task :generate do
|
|
22
|
+
support = OpenapiRuby::Generator::RakeTaskSupport
|
|
23
|
+
framework = ENV.fetch("FRAMEWORK") { support.detect_test_framework }.to_s
|
|
24
|
+
pattern = ENV.fetch("PATTERN") { support.default_pattern_for(framework) }
|
|
25
|
+
|
|
26
|
+
# Spawn a subprocess so the host's env defaults to "test" cleanly,
|
|
27
|
+
# just like rswag did with RSpec::Core::RakeTask.
|
|
28
|
+
script = support.generate_script(framework, pattern)
|
|
29
|
+
command = "bundle exec ruby -e #{Shellwords.escape(script)}"
|
|
30
|
+
|
|
31
|
+
puts "Generating OpenAPI schemas (#{framework})..."
|
|
32
|
+
system(support.subprocess_env, command) || abort("Schema generation failed")
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
OpenapiRuby::RakeTasks.install!
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenapiRuby
|
|
4
|
+
# Host-neutral logic behind the served schema documents and the Swagger UI.
|
|
5
|
+
# The Rails controllers and RackApp are both thin shells over this, so the
|
|
6
|
+
# two hosts cannot drift apart.
|
|
7
|
+
module Serving
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
def schema_names
|
|
11
|
+
OpenapiRuby.configuration.schemas.keys.map(&:to_s)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def schema_config_for(schema_name)
|
|
15
|
+
OpenapiRuby.configuration.schemas[schema_name.to_sym]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def schema_file_path(schema_name)
|
|
19
|
+
config = OpenapiRuby.configuration
|
|
20
|
+
ext = (config.schema_output_format == :json) ? "json" : "yaml"
|
|
21
|
+
File.join(OpenapiRuby.app_root, config.schema_output_dir, "#{schema_name}.#{ext}")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def schema_format
|
|
25
|
+
(OpenapiRuby.configuration.schema_output_format == :json) ? :json : :yaml
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Returns [content, content_type], or nil when the schema is unknown or
|
|
29
|
+
# has not been generated yet — callers turn that into a 404.
|
|
30
|
+
#
|
|
31
|
+
# `request` is handed to the configured :openapi_filter untouched. Rails
|
|
32
|
+
# passes an ActionDispatch::Request and RackApp a Rack::Request; the hook
|
|
33
|
+
# only ever needs the shared Rack request API.
|
|
34
|
+
def schema_document(schema_name, request: nil)
|
|
35
|
+
schema_config = schema_config_for(schema_name)
|
|
36
|
+
return nil unless schema_config
|
|
37
|
+
|
|
38
|
+
file_path = schema_file_path(schema_name)
|
|
39
|
+
return nil unless File.exist?(file_path)
|
|
40
|
+
|
|
41
|
+
content = File.read(file_path)
|
|
42
|
+
|
|
43
|
+
if schema_config[:openapi_filter]
|
|
44
|
+
doc = parse_content(file_path, content)
|
|
45
|
+
schema_config[:openapi_filter].call(doc, request)
|
|
46
|
+
content = serialize_doc(file_path, doc)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
[content, content_type_for(file_path)]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def content_type_for(file_path)
|
|
53
|
+
file_path.end_with?(".json") ? "application/json" : "application/x-yaml"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def parse_content(file_path, content)
|
|
57
|
+
if file_path.end_with?(".json")
|
|
58
|
+
JSON.parse(content)
|
|
59
|
+
else
|
|
60
|
+
YAML.safe_load(content, permitted_classes: [Date, Time])
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def serialize_doc(file_path, doc)
|
|
65
|
+
if file_path.end_with?(".json")
|
|
66
|
+
JSON.pretty_generate(doc)
|
|
67
|
+
else
|
|
68
|
+
doc.to_yaml
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def oauth2_redirect_file
|
|
73
|
+
File.join(gem_root, "app", "views", "openapi_ruby", "oauth2_redirect.html")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def gem_root
|
|
77
|
+
File.expand_path("../..", __dir__)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# `schema_urls` is an array of {url:, name:} — the caller builds them,
|
|
81
|
+
# since only it knows how the docs are mounted.
|
|
82
|
+
def swagger_ui_html(schema_urls:, ui_config: {})
|
|
83
|
+
<<~HTML
|
|
84
|
+
<!DOCTYPE html>
|
|
85
|
+
<html lang="en">
|
|
86
|
+
<head>
|
|
87
|
+
<meta charset="UTF-8">
|
|
88
|
+
<title>#{ui_config[:title] || "API Documentation"}</title>
|
|
89
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css">
|
|
90
|
+
<style>
|
|
91
|
+
html { box-sizing: border-box; overflow-y: scroll; }
|
|
92
|
+
*, *:before, *:after { box-sizing: inherit; }
|
|
93
|
+
body { margin: 0; background: #fafafa; }
|
|
94
|
+
</style>
|
|
95
|
+
</head>
|
|
96
|
+
<body>
|
|
97
|
+
<div id="swagger-ui"></div>
|
|
98
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
99
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-standalone-preset.js"></script>
|
|
100
|
+
<script>
|
|
101
|
+
SwaggerUIBundle({
|
|
102
|
+
#{schema_urls_js(schema_urls)},
|
|
103
|
+
dom_id: '#swagger-ui',
|
|
104
|
+
deepLinking: true,
|
|
105
|
+
presets: [
|
|
106
|
+
SwaggerUIBundle.presets.apis,
|
|
107
|
+
SwaggerUIStandalonePreset
|
|
108
|
+
],
|
|
109
|
+
plugins: [
|
|
110
|
+
SwaggerUIBundle.plugins.DownloadUrl
|
|
111
|
+
],
|
|
112
|
+
layout: "#{(schema_urls.size > 1) ? "StandaloneLayout" : "BaseLayout"}",
|
|
113
|
+
#{ui_config_js(ui_config)}
|
|
114
|
+
});
|
|
115
|
+
</script>
|
|
116
|
+
</body>
|
|
117
|
+
</html>
|
|
118
|
+
HTML
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def schema_urls_js(schema_urls)
|
|
122
|
+
if schema_urls.size > 1
|
|
123
|
+
"urls: #{schema_urls.to_json}"
|
|
124
|
+
else
|
|
125
|
+
"url: \"#{schema_urls.first&.fetch(:url)}\""
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def ui_config_js(ui_config)
|
|
130
|
+
ui_config.except(:title).map { |k, v|
|
|
131
|
+
"#{k}: #{v.to_json}"
|
|
132
|
+
}.join(",\n ")
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenapiRuby
|
|
4
|
+
module Testing
|
|
5
|
+
# Bridges the adapters onto whichever request-issuing API the host's test
|
|
6
|
+
# context provides. Rails integration tests take keyword arguments and
|
|
7
|
+
# expose `response`; rack-test (Hanami, Sinatra, bare Rack) takes
|
|
8
|
+
# positional arguments plus a Rack env and exposes `last_response`.
|
|
9
|
+
#
|
|
10
|
+
# Both response objects answer #status, #body and #headers, so callers
|
|
11
|
+
# need no further normalisation.
|
|
12
|
+
module Transport
|
|
13
|
+
# Rails is checked first: a suite can include Rack::Test::Methods
|
|
14
|
+
# alongside the integration helpers, and in that case the Rails session
|
|
15
|
+
# is the one that boots the app under test.
|
|
16
|
+
def self.for(context)
|
|
17
|
+
if context.respond_to?(:integration_session)
|
|
18
|
+
RailsIntegration.new(context)
|
|
19
|
+
elsif context.respond_to?(:last_response)
|
|
20
|
+
require_app!(context)
|
|
21
|
+
RackTest.new(context)
|
|
22
|
+
elsif OpenapiRuby.rails_host?
|
|
23
|
+
# A hand-rolled harness that defines the verb methods itself. Left
|
|
24
|
+
# working rather than second-guessed.
|
|
25
|
+
RailsIntegration.new(context)
|
|
26
|
+
else
|
|
27
|
+
# Without rack-test, dispatch would land on the example-group DSL's
|
|
28
|
+
# own `get`, and the user would get told that `get` is unavailable
|
|
29
|
+
# inside an example — true, and no help at all here.
|
|
30
|
+
raise OpenapiRuby::Error,
|
|
31
|
+
"openapi_ruby found no way to issue requests from #{describe(context)}. " \
|
|
32
|
+
"Add rack-test to your bundle, `include Rack::Test::Methods`, and define `app`."
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# rack-test resolves `app` lazily, so a missing one surfaces as a bare
|
|
37
|
+
# NameError from inside the gem rather than as the setup mistake it is.
|
|
38
|
+
def self.require_app!(context)
|
|
39
|
+
return if context.respond_to?(:app)
|
|
40
|
+
|
|
41
|
+
raise OpenapiRuby::Error,
|
|
42
|
+
"openapi_ruby needs the Rack app under test in #{describe(context)}. " \
|
|
43
|
+
"Define it as `let(:app) { MyApp }` in RSpec, or an `app` method in Minitest."
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.describe(context)
|
|
47
|
+
context.is_a?(Class) ? context.name.to_s : context.class.name.to_s
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class RailsIntegration
|
|
51
|
+
def initialize(context)
|
|
52
|
+
@context = context
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def dispatch(method, path, params: nil, headers: nil)
|
|
56
|
+
args = {}
|
|
57
|
+
args[:params] = params unless params.nil?
|
|
58
|
+
args[:headers] = headers unless headers.nil?
|
|
59
|
+
@context.send(method.to_sym, path, **args)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def response
|
|
63
|
+
@context.response
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
class RackTest
|
|
68
|
+
# Rack keeps these two out of the HTTP_ namespace.
|
|
69
|
+
UNPREFIXED_HEADERS = {
|
|
70
|
+
"content-type" => "CONTENT_TYPE",
|
|
71
|
+
"content-length" => "CONTENT_LENGTH"
|
|
72
|
+
}.freeze
|
|
73
|
+
|
|
74
|
+
def initialize(context)
|
|
75
|
+
@context = context
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# rack-test treats a String `params` as the request body and a Hash as
|
|
79
|
+
# form/query data, which is the same split the adapters already make.
|
|
80
|
+
def dispatch(method, path, params: nil, headers: nil)
|
|
81
|
+
@context.send(method.to_sym, path, params || {}, rack_env(headers || {}))
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def response
|
|
85
|
+
@context.last_response
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
def rack_env(headers)
|
|
91
|
+
headers.each_with_object({}) do |(name, value), env|
|
|
92
|
+
key = name.to_s
|
|
93
|
+
env[UNPREFIXED_HEADERS.fetch(key.downcase) { "HTTP_#{key.upcase.tr("-", "_")}" }] = value.to_s
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
data/lib/openapi_ruby/version.rb
CHANGED
data/lib/openapi_ruby.rb
CHANGED
|
@@ -12,6 +12,7 @@ require "yaml"
|
|
|
12
12
|
|
|
13
13
|
require_relative "openapi_ruby/version"
|
|
14
14
|
require_relative "openapi_ruby/errors"
|
|
15
|
+
require_relative "openapi_ruby/host"
|
|
15
16
|
require_relative "openapi_ruby/configuration"
|
|
16
17
|
|
|
17
18
|
module OpenapiRuby
|
|
@@ -57,6 +58,7 @@ require_relative "openapi_ruby/dsl/response_context"
|
|
|
57
58
|
require_relative "openapi_ruby/dsl/operation_context"
|
|
58
59
|
require_relative "openapi_ruby/dsl/context"
|
|
59
60
|
require_relative "openapi_ruby/dsl/metadata_store"
|
|
61
|
+
require_relative "openapi_ruby/testing/transport"
|
|
60
62
|
require_relative "openapi_ruby/testing/request_builder"
|
|
61
63
|
require_relative "openapi_ruby/testing/response_validator"
|
|
62
64
|
require_relative "openapi_ruby/testing/request_validator"
|
|
@@ -70,6 +72,9 @@ require_relative "openapi_ruby/middleware/error_handler"
|
|
|
70
72
|
require_relative "openapi_ruby/middleware/schema_resolver"
|
|
71
73
|
require_relative "openapi_ruby/middleware/request_validation"
|
|
72
74
|
require_relative "openapi_ruby/middleware/response_validation"
|
|
75
|
+
require_relative "openapi_ruby/middleware/installer"
|
|
76
|
+
require_relative "openapi_ruby/serving"
|
|
77
|
+
require_relative "openapi_ruby/rack_app"
|
|
73
78
|
require_relative "openapi_ruby/controller_helpers"
|
|
74
79
|
if defined?(Rails::Engine)
|
|
75
80
|
require_relative "openapi_ruby/engine"
|
data/lib/tasks/openapi_ruby.rake
CHANGED
|
@@ -1,21 +1,3 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "openapi_ruby/
|
|
4
|
-
|
|
5
|
-
namespace :openapi_ruby do
|
|
6
|
-
desc "Generate OpenAPI schema files from spec definitions and components"
|
|
7
|
-
task :generate do
|
|
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) }
|
|
11
|
-
|
|
12
|
-
# Spawn a subprocess so RAILS_ENV defaults to "test" cleanly,
|
|
13
|
-
# just like rswag did with RSpec::Core::RakeTask.
|
|
14
|
-
env = {"RAILS_ENV" => ENV.fetch("RAILS_ENV", "test"), "OPENAPI_RUBY_GENERATING" => "true"}
|
|
15
|
-
script = support.generate_script(framework, pattern)
|
|
16
|
-
command = "bundle exec ruby -e #{Shellwords.escape(script)}"
|
|
17
|
-
|
|
18
|
-
puts "Generating OpenAPI schemas (#{framework})..."
|
|
19
|
-
system(env, command) || abort("Schema generation failed")
|
|
20
|
-
end
|
|
21
|
-
end
|
|
3
|
+
require "openapi_ruby/rake_tasks"
|
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: 4.0
|
|
4
|
+
version: 4.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Morten Hartvig
|
|
@@ -51,23 +51,9 @@ dependencies:
|
|
|
51
51
|
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: '2.0'
|
|
54
|
-
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
requirements:
|
|
58
|
-
- - ">="
|
|
59
|
-
- !ruby/object:Gem::Version
|
|
60
|
-
version: '7.0'
|
|
61
|
-
type: :runtime
|
|
62
|
-
prerelease: false
|
|
63
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
-
requirements:
|
|
65
|
-
- - ">="
|
|
66
|
-
- !ruby/object:Gem::Version
|
|
67
|
-
version: '7.0'
|
|
68
|
-
description: A unified OpenAPI toolkit for Rails that combines test-driven spec generation,
|
|
69
|
-
reusable schema components as Ruby classes, and runtime request/response validation
|
|
70
|
-
middleware. Supports OpenAPI 3.0 and 3.1. Works with both RSpec and Minitest.
|
|
54
|
+
description: A unified OpenAPI toolkit for Rails and Hanami that combines test-driven
|
|
55
|
+
spec generation, reusable schema components as Ruby classes, and runtime request/response
|
|
56
|
+
validation middleware. Supports OpenAPI 3.0 and 3.1. Works with both RSpec and Minitest.
|
|
71
57
|
email:
|
|
72
58
|
- morten@hartvigsen.dev
|
|
73
59
|
executables: []
|
|
@@ -88,6 +74,7 @@ files:
|
|
|
88
74
|
- lib/generators/openapi_ruby/install/templates/openapi_helper.rb.tt
|
|
89
75
|
- lib/openapi-ruby.rb
|
|
90
76
|
- lib/openapi_ruby.rb
|
|
77
|
+
- lib/openapi_ruby/adapters/context_resolution.rb
|
|
91
78
|
- lib/openapi_ruby/adapters/minitest.rb
|
|
92
79
|
- lib/openapi_ruby/adapters/rspec.rb
|
|
93
80
|
- lib/openapi_ruby/components/base.rb
|
|
@@ -109,19 +96,26 @@ files:
|
|
|
109
96
|
- lib/openapi_ruby/generator/rake_task_support.rb
|
|
110
97
|
- lib/openapi_ruby/generator/schema_writer.rb
|
|
111
98
|
- lib/openapi_ruby/generator/test_schema_suppressor.rb
|
|
99
|
+
- lib/openapi_ruby/hanami.rb
|
|
100
|
+
- lib/openapi_ruby/host.rb
|
|
112
101
|
- lib/openapi_ruby/middleware/coercion.rb
|
|
113
102
|
- lib/openapi_ruby/middleware/error_handler.rb
|
|
103
|
+
- lib/openapi_ruby/middleware/installer.rb
|
|
114
104
|
- lib/openapi_ruby/middleware/path_matcher.rb
|
|
115
105
|
- lib/openapi_ruby/middleware/request_validation.rb
|
|
116
106
|
- lib/openapi_ruby/middleware/response_validation.rb
|
|
117
107
|
- lib/openapi_ruby/middleware/schema_resolver.rb
|
|
118
108
|
- lib/openapi_ruby/minitest.rb
|
|
109
|
+
- lib/openapi_ruby/rack_app.rb
|
|
110
|
+
- lib/openapi_ruby/rake_tasks.rb
|
|
119
111
|
- lib/openapi_ruby/rspec.rb
|
|
112
|
+
- lib/openapi_ruby/serving.rb
|
|
120
113
|
- lib/openapi_ruby/testing/assertions.rb
|
|
121
114
|
- lib/openapi_ruby/testing/coverage.rb
|
|
122
115
|
- lib/openapi_ruby/testing/request_builder.rb
|
|
123
116
|
- lib/openapi_ruby/testing/request_validator.rb
|
|
124
117
|
- lib/openapi_ruby/testing/response_validator.rb
|
|
118
|
+
- lib/openapi_ruby/testing/transport.rb
|
|
125
119
|
- lib/openapi_ruby/version.rb
|
|
126
120
|
- lib/tasks/openapi_ruby.rake
|
|
127
121
|
homepage: https://github.com/openapi-ruby/openapi-ruby
|
|
@@ -148,6 +142,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
148
142
|
requirements: []
|
|
149
143
|
rubygems_version: 3.6.9
|
|
150
144
|
specification_version: 4
|
|
151
|
-
summary: OpenAPI 3.0/3.1 toolkit for Rails — spec generation, schema components,
|
|
152
|
-
runtime validation
|
|
145
|
+
summary: OpenAPI 3.0/3.1 toolkit for Rails and Hanami — spec generation, schema components,
|
|
146
|
+
and runtime validation
|
|
153
147
|
test_files: []
|