openapi_blocks 0.2.1 → 0.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/CHANGELOG.md +17 -0
- data/README.md +152 -85
- data/README.pt-BR.md +229 -342
- data/app/controllers/openapi_blocks/spec_controller.rb +48 -13
- data/config/routes.rb +2 -1
- data/lib/openapi_blocks/base.rb +3 -0
- data/lib/openapi_blocks/builder.rb +3 -1
- data/lib/openapi_blocks/controller.rb +40 -0
- data/lib/openapi_blocks/resource.rb +20 -0
- data/lib/openapi_blocks/serializer.rb +193 -0
- data/lib/openapi_blocks/spec/components.rb +14 -6
- data/lib/openapi_blocks/version.rb +1 -1
- data/lib/openapi_blocks.rb +4 -0
- metadata +18 -1
|
@@ -4,14 +4,19 @@ require "action_controller/api"
|
|
|
4
4
|
|
|
5
5
|
module OpenapiBlocks
|
|
6
6
|
class SpecController < ActionController::API # rubocop:disable Style/Documentation
|
|
7
|
-
SWAGGER_UI_CSS
|
|
8
|
-
SWAGGER_UI_STANDALONE_JS
|
|
9
|
-
SWAGGER_UI_JS
|
|
7
|
+
SWAGGER_UI_CSS = "https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui.css"
|
|
8
|
+
SWAGGER_UI_STANDALONE_JS = "https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-standalone-preset.js"
|
|
9
|
+
SWAGGER_UI_JS = "https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-bundle.js"
|
|
10
|
+
SCALAR_JS = "https://cdn.jsdelivr.net/npm/@scalar/api-reference"
|
|
10
11
|
|
|
11
12
|
def ui
|
|
12
13
|
render html: swagger_ui_html.html_safe
|
|
13
14
|
end
|
|
14
15
|
|
|
16
|
+
def scalar
|
|
17
|
+
render html: scalar_html.html_safe
|
|
18
|
+
end
|
|
19
|
+
|
|
15
20
|
def show
|
|
16
21
|
spec = OpenapiBlocks::Builder.build.deep_stringify_keys
|
|
17
22
|
spec["servers"] = swagger_ui_servers(spec)
|
|
@@ -25,6 +30,42 @@ module OpenapiBlocks
|
|
|
25
30
|
|
|
26
31
|
private
|
|
27
32
|
|
|
33
|
+
def scalar_html
|
|
34
|
+
spec_url = "#{swagger_spec_base_url}.json"
|
|
35
|
+
title = "#{OpenapiBlocks.configuration.info.title} - Scalar"
|
|
36
|
+
|
|
37
|
+
<<~HTML
|
|
38
|
+
<!doctype html>
|
|
39
|
+
<html lang="en">
|
|
40
|
+
<head>
|
|
41
|
+
<meta charset="utf-8" />
|
|
42
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
43
|
+
<title>#{title}</title>
|
|
44
|
+
</head>
|
|
45
|
+
<body>
|
|
46
|
+
<script
|
|
47
|
+
id="api-reference"
|
|
48
|
+
data-url="#{spec_url}"
|
|
49
|
+
data-configuration='#{scalar_configuration.to_json}'
|
|
50
|
+
></script>
|
|
51
|
+
<script src="#{SCALAR_JS}"></script>
|
|
52
|
+
</body>
|
|
53
|
+
</html>
|
|
54
|
+
HTML
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def scalar_configuration
|
|
58
|
+
{
|
|
59
|
+
theme: "default",
|
|
60
|
+
layout: "modern",
|
|
61
|
+
displayRequestDuration: true,
|
|
62
|
+
defaultHttpClient: {
|
|
63
|
+
targetKey: "ruby",
|
|
64
|
+
clientKey: "net_http"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
|
|
28
69
|
def swagger_ui_html # rubocop:disable Metrics/MethodLength
|
|
29
70
|
urls = swagger_ui_urls
|
|
30
71
|
|
|
@@ -69,22 +110,16 @@ module OpenapiBlocks
|
|
|
69
110
|
"#{OpenapiBlocks.configuration.info.title} - SwaggerUI"
|
|
70
111
|
end
|
|
71
112
|
|
|
72
|
-
def swagger_ui_urls
|
|
113
|
+
def swagger_ui_urls
|
|
73
114
|
spec_base = swagger_spec_base_url
|
|
74
|
-
servers
|
|
115
|
+
servers = OpenapiBlocks.configuration.to_h[:servers]
|
|
75
116
|
|
|
76
117
|
return default_swagger_ui_urls if servers.blank?
|
|
77
118
|
|
|
78
119
|
servers.flat_map do |server|
|
|
79
120
|
[
|
|
80
|
-
{
|
|
81
|
-
|
|
82
|
-
name: "#{server[:url]} JSON"
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
url: "#{spec_base}.yaml",
|
|
86
|
-
name: "#{server[:url]} YAML"
|
|
87
|
-
}
|
|
121
|
+
{ url: "#{spec_base}.json", name: "#{server[:url]} JSON" },
|
|
122
|
+
{ url: "#{spec_base}.yaml", name: "#{server[:url]} YAML" }
|
|
88
123
|
]
|
|
89
124
|
end
|
|
90
125
|
end
|
data/config/routes.rb
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
OpenapiBlocks::Engine.routes.draw do
|
|
4
|
-
root to: "spec#
|
|
4
|
+
root to: "spec#scalar"
|
|
5
|
+
get "swagger", to: "spec#ui"
|
|
5
6
|
get "openapi.json", to: "spec#show", defaults: { format: "json" }
|
|
6
7
|
get "openapi.yaml", to: "spec#show", defaults: { format: "yaml" }
|
|
7
8
|
end
|
data/lib/openapi_blocks/base.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module OpenapiBlocks
|
|
4
4
|
class Base # rubocop:disable Style/Documentation
|
|
5
|
+
include Serializer
|
|
6
|
+
|
|
5
7
|
class << self
|
|
6
8
|
attr_reader :_model, :_ignored, :_associations, :_virtual_attributes, :_operations, :_tags
|
|
7
9
|
|
|
@@ -40,6 +42,7 @@ module OpenapiBlocks
|
|
|
40
42
|
def infer_model
|
|
41
43
|
model_name = name
|
|
42
44
|
.gsub(/Openapi$/, "")
|
|
45
|
+
.gsub(/Resource$/, "")
|
|
43
46
|
.split("::")
|
|
44
47
|
.last
|
|
45
48
|
|
|
@@ -16,7 +16,9 @@ module OpenapiBlocks
|
|
|
16
16
|
|
|
17
17
|
def openapi_classes
|
|
18
18
|
ObjectSpace.each_object(Class).select do |klass|
|
|
19
|
-
|
|
19
|
+
name = Module.instance_method(:name).bind_call(klass)
|
|
20
|
+
name&.end_with?("Openapi") &&
|
|
21
|
+
(klass < OpenapiBlocks::Base || klass < OpenapiBlocks::Controller)
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenapiBlocks
|
|
4
|
+
class Controller # rubocop:disable Style/Documentation
|
|
5
|
+
class << self
|
|
6
|
+
attr_reader :_resource, :_operations, :_tags
|
|
7
|
+
|
|
8
|
+
def resource(klass)
|
|
9
|
+
@_resource = klass
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def model
|
|
13
|
+
@_resource&.model
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def _associations
|
|
17
|
+
@_resource&._associations
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def _virtual_attributes
|
|
21
|
+
@_resource&._virtual_attributes
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def _ignored
|
|
25
|
+
@_resource&._ignored
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def operation(action, &block)
|
|
29
|
+
@_operations ||= {}
|
|
30
|
+
builder = OperationBuilder.new
|
|
31
|
+
builder.instance_eval(&block) if block
|
|
32
|
+
@_operations[action] = builder
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def tags(*values)
|
|
36
|
+
values.any? ? @_tags = values : @_tags
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenapiBlocks
|
|
4
|
+
class Resource < Base # rubocop:disable Style/Documentation
|
|
5
|
+
class << self
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def infer_model
|
|
9
|
+
model_name = name
|
|
10
|
+
.gsub(/Resource$/, "")
|
|
11
|
+
.split("::")
|
|
12
|
+
.last
|
|
13
|
+
|
|
14
|
+
Object.const_get(model_name)
|
|
15
|
+
rescue NameError
|
|
16
|
+
raise Error, "Could not infer model from #{name}. Use `model ModelClass` to define it explicitly."
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenapiBlocks
|
|
4
|
+
module Serializer # rubocop:disable Style/Documentation
|
|
5
|
+
def self.included(base)
|
|
6
|
+
base.extend(ClassMethods)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module ClassMethods # rubocop:disable Metrics/ModuleLength,Style/Documentation
|
|
10
|
+
def serialize(resource, instance: nil) # rubocop:disable Lint/UnusedMethodArgument
|
|
11
|
+
extractor = compiled_extractor
|
|
12
|
+
if resource.respond_to?(:each)
|
|
13
|
+
resource.map { |r| extractor.call(r) }
|
|
14
|
+
else
|
|
15
|
+
extractor.call(resource)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_json(resource)
|
|
20
|
+
Oj.dump(serialize(resource), mode: :compat)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def fields
|
|
24
|
+
@fields ||= resolve_fields
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def compiled_extractor
|
|
28
|
+
@compiled_extractor ||= build_compiled_extractor
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def build_compiled_extractor # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
|
34
|
+
classified = classify_fields
|
|
35
|
+
|
|
36
|
+
model_lines = classified[:model].map { |f| %("#{f}" => object.public_send(:#{f})) }
|
|
37
|
+
virtual_lines = classified[:virtual].map { |f| %("#{f}" => inst.public_send(:#{f})) }
|
|
38
|
+
delegated_lines = classified[:delegated].map { |f| %("#{f}" => object.public_send(:#{f})) }
|
|
39
|
+
assoc_lines = classified[:association].map do |f|
|
|
40
|
+
%("#{f}" => _serialize_assoc_#{f}(object))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
classified[:association].each { |field| build_assoc_method(field) }
|
|
44
|
+
|
|
45
|
+
all_lines = (model_lines + delegated_lines + virtual_lines + assoc_lines).join(",\n ")
|
|
46
|
+
|
|
47
|
+
if classified[:virtual].any?
|
|
48
|
+
serializer_klass = self
|
|
49
|
+
class_eval(<<~RUBY, __FILE__, __LINE__ + 1) # rubocop:disable Style/DocumentDynamicEvalDefinition
|
|
50
|
+
def self._extract(object)
|
|
51
|
+
inst = #{serializer_klass}.new(object)
|
|
52
|
+
{
|
|
53
|
+
#{all_lines}
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
RUBY
|
|
57
|
+
else
|
|
58
|
+
class_eval(<<~RUBY, __FILE__, __LINE__ + 1) # rubocop:disable Style/DocumentDynamicEvalDefinition
|
|
59
|
+
def self._extract(object)
|
|
60
|
+
{
|
|
61
|
+
#{all_lines}
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
RUBY
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
method(:_extract)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def build_assoc_method(field) # rubocop:disable Metrics/MethodLength
|
|
71
|
+
assoc = assoc_metadata_by_name[field]
|
|
72
|
+
assoc_name = assoc[:name]
|
|
73
|
+
serializer = resolve_assoc_serializer(assoc_name)
|
|
74
|
+
|
|
75
|
+
if serializer.nil?
|
|
76
|
+
class_eval(<<~RUBY, __FILE__, __LINE__ + 1) # rubocop:disable Style/DocumentDynamicEvalDefinition
|
|
77
|
+
def self._serialize_assoc_#{field}(object)
|
|
78
|
+
object.public_send(:#{assoc_name}).as_json
|
|
79
|
+
end
|
|
80
|
+
RUBY
|
|
81
|
+
return
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
if assoc[:type] == :array
|
|
85
|
+
class_eval(<<~RUBY, __FILE__, __LINE__ + 1) # rubocop:disable Style/DocumentDynamicEvalDefinition
|
|
86
|
+
def self._serialize_assoc_#{field}(object)
|
|
87
|
+
val = object.public_send(:#{assoc_name})
|
|
88
|
+
return nil if val.nil?
|
|
89
|
+
val.map { |v| #{serializer}.serialize(v) }
|
|
90
|
+
end
|
|
91
|
+
RUBY
|
|
92
|
+
else
|
|
93
|
+
class_eval(<<~RUBY, __FILE__, __LINE__ + 1) # rubocop:disable Style/DocumentDynamicEvalDefinition
|
|
94
|
+
def self._serialize_assoc_#{field}(object)
|
|
95
|
+
val = object.public_send(:#{assoc_name})
|
|
96
|
+
val.nil? ? nil : #{serializer}.serialize(val)
|
|
97
|
+
end
|
|
98
|
+
RUBY
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def resolve_assoc_serializer(assoc_name)
|
|
103
|
+
classified = assoc_name.to_s.classify
|
|
104
|
+
|
|
105
|
+
["#{classified}Resource", "#{classified}Openapi"].each do |name|
|
|
106
|
+
klass = Object.const_get(name)
|
|
107
|
+
return klass._resource if klass.respond_to?(:_resource) && klass._resource
|
|
108
|
+
return klass if klass.respond_to?(:serialize)
|
|
109
|
+
rescue NameError
|
|
110
|
+
next
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
nil
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def classify_fields # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
117
|
+
model_set = Set.new(resolve_model_fields)
|
|
118
|
+
assoc_set = Set.new(assoc_metadata_by_name.keys)
|
|
119
|
+
virtual_set = Set.new(
|
|
120
|
+
Array(_virtual_attributes).map { |a| a[:name].to_s }
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
result = { model: [], virtual: [], delegated: [], association: [] }
|
|
124
|
+
fields.each do |field|
|
|
125
|
+
result[if assoc_set.include?(field)
|
|
126
|
+
:association
|
|
127
|
+
elsif model_set.include?(field)
|
|
128
|
+
:model
|
|
129
|
+
elsif virtual_set.include?(field) && method_defined?(field.to_sym)
|
|
130
|
+
:virtual # método definido no resource
|
|
131
|
+
elsif virtual_set.include?(field)
|
|
132
|
+
:delegated # método definido no model
|
|
133
|
+
else # rubocop:disable Lint/DuplicateBranch
|
|
134
|
+
:delegated
|
|
135
|
+
end] << field
|
|
136
|
+
end
|
|
137
|
+
result
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def assoc_metadata_by_name
|
|
141
|
+
@assoc_metadata_by_name ||= begin
|
|
142
|
+
klass = self
|
|
143
|
+
result = {}
|
|
144
|
+
while klass && klass != OpenapiBlocks::Base
|
|
145
|
+
Array(klass._associations)
|
|
146
|
+
.each { |a| result[a[:name].to_s] ||= a }
|
|
147
|
+
klass = klass.superclass
|
|
148
|
+
end
|
|
149
|
+
result
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def resolve_fields # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
|
154
|
+
klass = self
|
|
155
|
+
|
|
156
|
+
model_fields = resolve_model_fields
|
|
157
|
+
virtual_fields = []
|
|
158
|
+
ignored_fields = []
|
|
159
|
+
assoc_fields = []
|
|
160
|
+
|
|
161
|
+
while klass && klass != OpenapiBlocks::Base
|
|
162
|
+
virtual_fields += Array(klass._virtual_attributes)
|
|
163
|
+
.map { |a| a[:name].to_s }
|
|
164
|
+
ignored_fields += Array(klass._ignored)
|
|
165
|
+
assoc_fields += Array(klass._associations)
|
|
166
|
+
.map { |a| a[:name].to_s }
|
|
167
|
+
klass = klass.superclass
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
(model_fields + virtual_fields + assoc_fields - ignored_fields).uniq
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def resolve_model_fields
|
|
174
|
+
klass = self
|
|
175
|
+
while klass && klass != OpenapiBlocks::Base
|
|
176
|
+
begin
|
|
177
|
+
return klass.model.column_names
|
|
178
|
+
rescue StandardError
|
|
179
|
+
klass = klass.superclass
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
[]
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
attr_reader :object, :parent
|
|
187
|
+
|
|
188
|
+
def initialize(object, parent = nil)
|
|
189
|
+
@object = object
|
|
190
|
+
@parent = parent
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
@@ -12,17 +12,25 @@ module OpenapiBlocks
|
|
|
12
12
|
@openapi_classes = openapi_classes
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def build # rubocop:disable Metrics/AbcSize
|
|
15
|
+
def build # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
|
16
16
|
schemas = @openapi_classes.each_with_object({}) do |klass, hash|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
schema_klass = klass.respond_to?(:_resource) && klass._resource ? klass._resource : klass
|
|
18
|
+
|
|
19
|
+
begin
|
|
20
|
+
next unless schema_klass.model
|
|
21
|
+
rescue StandardError
|
|
22
|
+
next
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
schema_name = schema_klass.model.name
|
|
26
|
+
extractor = Schema::Extractor.new(schema_klass)
|
|
27
|
+
validator = Schema::Validator.new(schema_klass.model)
|
|
20
28
|
|
|
21
29
|
schema = extractor.extract
|
|
22
30
|
schema[:properties] = merge_validations(schema[:properties], validator.extract)
|
|
23
31
|
|
|
24
|
-
hash[schema_name]
|
|
25
|
-
hash["#{schema_name}Input"]
|
|
32
|
+
hash[schema_name] = schema
|
|
33
|
+
hash["#{schema_name}Input"] = build_input(schema, schema_klass)
|
|
26
34
|
end
|
|
27
35
|
|
|
28
36
|
{ schemas: schemas }
|
data/lib/openapi_blocks.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "active_support/all"
|
|
4
4
|
require "active_record"
|
|
5
|
+
require "oj"
|
|
5
6
|
|
|
6
7
|
require_relative "openapi_blocks/version"
|
|
7
8
|
require_relative "openapi_blocks/configuration"
|
|
@@ -17,10 +18,13 @@ require_relative "openapi_blocks/spec/components"
|
|
|
17
18
|
require_relative "openapi_blocks/spec/paths"
|
|
18
19
|
require_relative "openapi_blocks/spec/document"
|
|
19
20
|
require_relative "openapi_blocks/builder"
|
|
21
|
+
require_relative "openapi_blocks/serializer"
|
|
20
22
|
require_relative "openapi_blocks/base"
|
|
21
23
|
require_relative "openapi_blocks/engine"
|
|
22
24
|
require_relative "openapi_blocks/railtie"
|
|
23
25
|
require_relative "openapi_blocks/operation_builder"
|
|
26
|
+
require_relative "openapi_blocks/resource"
|
|
27
|
+
require_relative "openapi_blocks/controller"
|
|
24
28
|
|
|
25
29
|
module OpenapiBlocks # rubocop:disable Style/Documentation
|
|
26
30
|
class Error < StandardError; end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openapi_blocks
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Caio Santos
|
|
@@ -9,6 +9,20 @@ bindir: exe
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: oj
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '3.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '3.0'
|
|
12
26
|
- !ruby/object:Gem::Dependency
|
|
13
27
|
name: rails
|
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -134,16 +148,19 @@ files:
|
|
|
134
148
|
- lib/openapi_blocks/configuration/security_builder.rb
|
|
135
149
|
- lib/openapi_blocks/configuration/server_builder.rb
|
|
136
150
|
- lib/openapi_blocks/configuration/servers_builder.rb
|
|
151
|
+
- lib/openapi_blocks/controller.rb
|
|
137
152
|
- lib/openapi_blocks/engine.rb
|
|
138
153
|
- lib/openapi_blocks/file_watcher.rb
|
|
139
154
|
- lib/openapi_blocks/middleware.rb
|
|
140
155
|
- lib/openapi_blocks/operation_builder.rb
|
|
141
156
|
- lib/openapi_blocks/railtie.rb
|
|
157
|
+
- lib/openapi_blocks/resource.rb
|
|
142
158
|
- lib/openapi_blocks/routing/extractor.rb
|
|
143
159
|
- lib/openapi_blocks/routing/operation.rb
|
|
144
160
|
- lib/openapi_blocks/schema/extractor.rb
|
|
145
161
|
- lib/openapi_blocks/schema/types.rb
|
|
146
162
|
- lib/openapi_blocks/schema/validator.rb
|
|
163
|
+
- lib/openapi_blocks/serializer.rb
|
|
147
164
|
- lib/openapi_blocks/spec/components.rb
|
|
148
165
|
- lib/openapi_blocks/spec/document.rb
|
|
149
166
|
- lib/openapi_blocks/spec/paths.rb
|