openapi-ruby 4.1.0 → 5.0.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 +252 -11
- 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/generators/openapi_ruby/component/component_generator.rb +21 -1
- data/lib/openapi_ruby/adapters/context_resolution.rb +1 -1
- data/lib/openapi_ruby/adapters/minitest.rb +35 -8
- data/lib/openapi_ruby/adapters/rspec.rb +46 -15
- data/lib/openapi_ruby/components/loader.rb +15 -0
- data/lib/openapi_ruby/configuration.rb +13 -1
- data/lib/openapi_ruby/core/document_builder.rb +1 -0
- data/lib/openapi_ruby/dsl/context.rb +1 -1
- data/lib/openapi_ruby/dsl/operation_context.rb +1 -1
- data/lib/openapi_ruby/engine.rb +1 -38
- 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/parameter_names.rb +89 -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/request_builder.rb +1 -1
- data/lib/openapi_ruby/testing/request_validator.rb +15 -4
- data/lib/openapi_ruby/testing/transport.rb +99 -0
- data/lib/openapi_ruby/version.rb +1 -1
- data/lib/openapi_ruby.rb +6 -0
- data/lib/tasks/openapi_ruby.rake +1 -19
- metadata +14 -20
|
@@ -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
|
|
@@ -37,7 +37,7 @@ module OpenapiRuby
|
|
|
37
37
|
result = {}
|
|
38
38
|
query_params.each do |param|
|
|
39
39
|
name = param["name"]
|
|
40
|
-
result[
|
|
40
|
+
result[ParameterNames.wire_name(param)] = @param_values[name] if @param_values.key?(name)
|
|
41
41
|
end
|
|
42
42
|
result
|
|
43
43
|
end
|
|
@@ -39,19 +39,30 @@ module OpenapiRuby
|
|
|
39
39
|
|
|
40
40
|
private
|
|
41
41
|
|
|
42
|
+
# A value may arrive under the declared name or the camelized wire name,
|
|
43
|
+
# depending on whether the caller wrote it or an adapter already renamed
|
|
44
|
+
# it for the request. Both spellings resolve.
|
|
42
45
|
def extract_param_value(param, params, headers, path_params)
|
|
43
|
-
|
|
46
|
+
names = ParameterNames.lookup_names(param)
|
|
44
47
|
|
|
45
48
|
case param["in"]
|
|
46
49
|
when "query"
|
|
47
|
-
params
|
|
50
|
+
fetch_any(params, names)
|
|
48
51
|
when "path"
|
|
49
|
-
path_params
|
|
52
|
+
fetch_any(path_params, names)
|
|
50
53
|
when "header"
|
|
51
|
-
headers
|
|
54
|
+
fetch_any(headers, names.flat_map { |name| [name, name.downcase] })
|
|
52
55
|
end
|
|
53
56
|
end
|
|
54
57
|
|
|
58
|
+
def fetch_any(store, names)
|
|
59
|
+
names.each do |name|
|
|
60
|
+
value = store[name.to_sym] || store[name.to_s]
|
|
61
|
+
return value if value
|
|
62
|
+
end
|
|
63
|
+
nil
|
|
64
|
+
end
|
|
65
|
+
|
|
55
66
|
def validate_request_body(operation, body)
|
|
56
67
|
errors = []
|
|
57
68
|
rb_spec = operation.request_body_definition
|
|
@@ -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
|
|
@@ -53,10 +54,12 @@ require_relative "openapi_ruby/components/key_transformer"
|
|
|
53
54
|
require_relative "openapi_ruby/components/registry"
|
|
54
55
|
require_relative "openapi_ruby/components/base"
|
|
55
56
|
require_relative "openapi_ruby/components/loader"
|
|
57
|
+
require_relative "openapi_ruby/parameter_names"
|
|
56
58
|
require_relative "openapi_ruby/dsl/response_context"
|
|
57
59
|
require_relative "openapi_ruby/dsl/operation_context"
|
|
58
60
|
require_relative "openapi_ruby/dsl/context"
|
|
59
61
|
require_relative "openapi_ruby/dsl/metadata_store"
|
|
62
|
+
require_relative "openapi_ruby/testing/transport"
|
|
60
63
|
require_relative "openapi_ruby/testing/request_builder"
|
|
61
64
|
require_relative "openapi_ruby/testing/response_validator"
|
|
62
65
|
require_relative "openapi_ruby/testing/request_validator"
|
|
@@ -70,6 +73,9 @@ require_relative "openapi_ruby/middleware/error_handler"
|
|
|
70
73
|
require_relative "openapi_ruby/middleware/schema_resolver"
|
|
71
74
|
require_relative "openapi_ruby/middleware/request_validation"
|
|
72
75
|
require_relative "openapi_ruby/middleware/response_validation"
|
|
76
|
+
require_relative "openapi_ruby/middleware/installer"
|
|
77
|
+
require_relative "openapi_ruby/serving"
|
|
78
|
+
require_relative "openapi_ruby/rack_app"
|
|
73
79
|
require_relative "openapi_ruby/controller_helpers"
|
|
74
80
|
if defined?(Rails::Engine)
|
|
75
81
|
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
|
+
version: 5.0.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: []
|
|
@@ -110,19 +96,27 @@ files:
|
|
|
110
96
|
- lib/openapi_ruby/generator/rake_task_support.rb
|
|
111
97
|
- lib/openapi_ruby/generator/schema_writer.rb
|
|
112
98
|
- lib/openapi_ruby/generator/test_schema_suppressor.rb
|
|
99
|
+
- lib/openapi_ruby/hanami.rb
|
|
100
|
+
- lib/openapi_ruby/host.rb
|
|
113
101
|
- lib/openapi_ruby/middleware/coercion.rb
|
|
114
102
|
- lib/openapi_ruby/middleware/error_handler.rb
|
|
103
|
+
- lib/openapi_ruby/middleware/installer.rb
|
|
115
104
|
- lib/openapi_ruby/middleware/path_matcher.rb
|
|
116
105
|
- lib/openapi_ruby/middleware/request_validation.rb
|
|
117
106
|
- lib/openapi_ruby/middleware/response_validation.rb
|
|
118
107
|
- lib/openapi_ruby/middleware/schema_resolver.rb
|
|
119
108
|
- lib/openapi_ruby/minitest.rb
|
|
109
|
+
- lib/openapi_ruby/parameter_names.rb
|
|
110
|
+
- lib/openapi_ruby/rack_app.rb
|
|
111
|
+
- lib/openapi_ruby/rake_tasks.rb
|
|
120
112
|
- lib/openapi_ruby/rspec.rb
|
|
113
|
+
- lib/openapi_ruby/serving.rb
|
|
121
114
|
- lib/openapi_ruby/testing/assertions.rb
|
|
122
115
|
- lib/openapi_ruby/testing/coverage.rb
|
|
123
116
|
- lib/openapi_ruby/testing/request_builder.rb
|
|
124
117
|
- lib/openapi_ruby/testing/request_validator.rb
|
|
125
118
|
- lib/openapi_ruby/testing/response_validator.rb
|
|
119
|
+
- lib/openapi_ruby/testing/transport.rb
|
|
126
120
|
- lib/openapi_ruby/version.rb
|
|
127
121
|
- lib/tasks/openapi_ruby.rake
|
|
128
122
|
homepage: https://github.com/openapi-ruby/openapi-ruby
|
|
@@ -149,6 +143,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
149
143
|
requirements: []
|
|
150
144
|
rubygems_version: 3.6.9
|
|
151
145
|
specification_version: 4
|
|
152
|
-
summary: OpenAPI 3.0/3.1 toolkit for Rails — spec generation, schema components,
|
|
153
|
-
runtime validation
|
|
146
|
+
summary: OpenAPI 3.0/3.1 toolkit for Rails and Hanami — spec generation, schema components,
|
|
147
|
+
and runtime validation
|
|
154
148
|
test_files: []
|