openapi_blocks 0.3.1 → 0.5.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 +45 -4
- data/README.md +188 -85
- data/README.pt-BR.md +222 -130
- data/app/controllers/openapi_blocks/spec_controller.rb +2 -2
- data/lib/generators/openapi_blocks/install/install_generator.rb +19 -0
- data/lib/generators/openapi_blocks/install/templates/initializer.rb.tt +36 -0
- data/lib/generators/openapi_blocks/openapi/openapi_generator.rb +15 -0
- data/lib/generators/openapi_blocks/openapi/templates/openapi.rb.tt +48 -0
- data/lib/generators/openapi_blocks/serializer/serializer_generator.rb +15 -0
- data/lib/generators/openapi_blocks/serializer/templates/serializer.rb.tt +15 -0
- data/lib/openapi_blocks/auto_serialize.rb +54 -0
- data/lib/openapi_blocks/base.rb +6 -35
- data/lib/openapi_blocks/builder.rb +34 -2
- data/lib/openapi_blocks/concerns/documentable.rb +26 -0
- data/lib/openapi_blocks/concerns/schemable.rb +45 -0
- data/lib/openapi_blocks/configuration.rb +8 -1
- data/lib/openapi_blocks/controller.rb +7 -27
- data/lib/openapi_blocks/railtie.rb +14 -2
- data/lib/openapi_blocks/registry.rb +76 -0
- data/lib/openapi_blocks/serialization.rb +197 -0
- data/lib/openapi_blocks/serializer.rb +12 -182
- data/lib/openapi_blocks/spec/components.rb +6 -4
- data/lib/openapi_blocks/version.rb +1 -1
- data/lib/openapi_blocks.rb +7 -3
- metadata +17 -5
- data/lib/openapi_blocks/resource.rb +0 -20
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenapiBlocks
|
|
4
|
+
module Serialization # 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 classify_fields # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
103
|
+
model_set = Set.new(resolve_model_fields)
|
|
104
|
+
assoc_set = Set.new(assoc_metadata_by_name.keys)
|
|
105
|
+
virtual_set = Set.new(
|
|
106
|
+
Array(_virtual_attributes).map { |a| a[:name].to_s }
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
result = { model: [], virtual: [], delegated: [], association: [] }
|
|
110
|
+
fields.each do |field|
|
|
111
|
+
result[if assoc_set.include?(field)
|
|
112
|
+
:association
|
|
113
|
+
elsif model_set.include?(field)
|
|
114
|
+
:model
|
|
115
|
+
elsif virtual_set.include?(field) && method_defined?(field.to_sym)
|
|
116
|
+
:virtual # método definido no resource
|
|
117
|
+
elsif virtual_set.include?(field)
|
|
118
|
+
:delegated # método definido no model
|
|
119
|
+
else # rubocop:disable Lint/DuplicateBranch
|
|
120
|
+
:delegated
|
|
121
|
+
end] << field
|
|
122
|
+
end
|
|
123
|
+
result
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def assoc_metadata_by_name
|
|
127
|
+
@assoc_metadata_by_name ||= begin
|
|
128
|
+
klass = self
|
|
129
|
+
result = {}
|
|
130
|
+
while klass && klass != serialization_sentinel
|
|
131
|
+
Array(klass._associations)
|
|
132
|
+
.each { |a| result[a[:name].to_s] ||= a }
|
|
133
|
+
klass = klass.superclass
|
|
134
|
+
end
|
|
135
|
+
result
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def resolve_fields # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
|
140
|
+
klass = self
|
|
141
|
+
sentinel = serialization_sentinel
|
|
142
|
+
|
|
143
|
+
model_fields = resolve_model_fields
|
|
144
|
+
virtual_fields = []
|
|
145
|
+
ignored_fields = []
|
|
146
|
+
assoc_fields = []
|
|
147
|
+
|
|
148
|
+
while klass && klass != sentinel
|
|
149
|
+
virtual_fields += Array(klass._virtual_attributes).map { |a| a[:name].to_s }
|
|
150
|
+
ignored_fields += Array(klass._ignored)
|
|
151
|
+
assoc_fields += Array(klass._associations).map { |a| a[:name].to_s }
|
|
152
|
+
klass = klass.superclass
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
(model_fields + virtual_fields + assoc_fields - ignored_fields).uniq
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def resolve_model_fields
|
|
159
|
+
klass = self
|
|
160
|
+
sentinel = serialization_sentinel
|
|
161
|
+
while klass && klass != sentinel
|
|
162
|
+
begin
|
|
163
|
+
return klass.model.column_names
|
|
164
|
+
rescue StandardError
|
|
165
|
+
klass = klass.superclass
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
[]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def serialization_sentinel
|
|
172
|
+
raise NotImplementedError
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def resolve_assoc_serializer(assoc_name)
|
|
176
|
+
classified = assoc_name.to_s.classify
|
|
177
|
+
|
|
178
|
+
["#{classified}Serializer", "#{classified}Openapi"].each do |name|
|
|
179
|
+
klass = Object.const_get(name)
|
|
180
|
+
return klass._resource if klass.respond_to?(:_resource) && klass._resource
|
|
181
|
+
return klass if klass.respond_to?(:serialize)
|
|
182
|
+
rescue NameError
|
|
183
|
+
next
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
nil
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
attr_reader :object, :parent
|
|
191
|
+
|
|
192
|
+
def initialize(object, parent = nil)
|
|
193
|
+
@object = object
|
|
194
|
+
@parent = parent
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
@@ -1,193 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module OpenapiBlocks
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
4
|
+
class Serializer # rubocop:disable Style/Documentation
|
|
5
|
+
include Concerns::Schemable
|
|
6
|
+
include Serialization
|
|
30
7
|
|
|
8
|
+
class << self
|
|
31
9
|
private
|
|
32
10
|
|
|
33
|
-
def
|
|
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 = []
|
|
11
|
+
def serialization_sentinel = OpenapiBlocks::Serializer
|
|
160
12
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
(model_fields + virtual_fields + assoc_fields - ignored_fields).uniq
|
|
13
|
+
def infer_model
|
|
14
|
+
model_name = name
|
|
15
|
+
.gsub(/Serializer$/, "")
|
|
16
|
+
.split("::").last
|
|
17
|
+
Object.const_get(model_name)
|
|
18
|
+
rescue NameError
|
|
19
|
+
raise Error, "Could not infer model from #{name}. Use `model ModelClass` to define it explicitly."
|
|
171
20
|
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
21
|
end
|
|
192
22
|
end
|
|
193
23
|
end
|
|
@@ -16,15 +16,17 @@ module OpenapiBlocks
|
|
|
16
16
|
schemas = @openapi_classes.each_with_object({}) do |klass, hash|
|
|
17
17
|
schema_klass = klass.respond_to?(:_resource) && klass._resource ? klass._resource : klass
|
|
18
18
|
|
|
19
|
-
begin
|
|
20
|
-
|
|
19
|
+
model = begin
|
|
20
|
+
schema_klass.model
|
|
21
21
|
rescue StandardError
|
|
22
22
|
next
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
next unless model
|
|
26
|
+
|
|
27
|
+
schema_name = model.name
|
|
26
28
|
extractor = Schema::Extractor.new(schema_klass)
|
|
27
|
-
validator = Schema::Validator.new(
|
|
29
|
+
validator = Schema::Validator.new(model)
|
|
28
30
|
|
|
29
31
|
schema = extractor.extract
|
|
30
32
|
schema[:properties] = merge_validations(schema[:properties], validator.extract)
|
data/lib/openapi_blocks.rb
CHANGED
|
@@ -18,13 +18,17 @@ require_relative "openapi_blocks/spec/components"
|
|
|
18
18
|
require_relative "openapi_blocks/spec/paths"
|
|
19
19
|
require_relative "openapi_blocks/spec/document"
|
|
20
20
|
require_relative "openapi_blocks/builder"
|
|
21
|
-
require_relative "openapi_blocks/serializer"
|
|
22
|
-
require_relative "openapi_blocks/base"
|
|
23
21
|
require_relative "openapi_blocks/engine"
|
|
24
22
|
require_relative "openapi_blocks/railtie"
|
|
25
23
|
require_relative "openapi_blocks/operation_builder"
|
|
26
|
-
require_relative "openapi_blocks/
|
|
24
|
+
require_relative "openapi_blocks/concerns/schemable"
|
|
25
|
+
require_relative "openapi_blocks/concerns/documentable"
|
|
26
|
+
require_relative "openapi_blocks/serialization"
|
|
27
|
+
require_relative "openapi_blocks/base"
|
|
28
|
+
require_relative "openapi_blocks/serializer"
|
|
27
29
|
require_relative "openapi_blocks/controller"
|
|
30
|
+
require_relative "openapi_blocks/registry"
|
|
31
|
+
require_relative "openapi_blocks/auto_serialize"
|
|
28
32
|
|
|
29
33
|
module OpenapiBlocks # rubocop:disable Style/Documentation
|
|
30
34
|
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.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Caio Santos
|
|
@@ -122,7 +122,9 @@ dependencies:
|
|
|
122
122
|
- !ruby/object:Gem::Version
|
|
123
123
|
version: '2.1'
|
|
124
124
|
description: Generates OpenAPI specs automatically from ActiveRecord models, ActiveModel
|
|
125
|
-
validations and Rails routes
|
|
125
|
+
validations and Rails routes. Includes a built-in serializer ~3.6x faster than as_json,
|
|
126
|
+
Scalar and Swagger UI out of the box, and optional auto-serialization via render
|
|
127
|
+
json:. Inspired by ActiveModel::Serializer.
|
|
126
128
|
email:
|
|
127
129
|
- caio.francelinosena@gmail.com
|
|
128
130
|
executables: []
|
|
@@ -137,10 +139,19 @@ files:
|
|
|
137
139
|
- Rakefile
|
|
138
140
|
- app/controllers/openapi_blocks/spec_controller.rb
|
|
139
141
|
- config/routes.rb
|
|
142
|
+
- lib/generators/openapi_blocks/install/install_generator.rb
|
|
143
|
+
- lib/generators/openapi_blocks/install/templates/initializer.rb.tt
|
|
144
|
+
- lib/generators/openapi_blocks/openapi/openapi_generator.rb
|
|
145
|
+
- lib/generators/openapi_blocks/openapi/templates/openapi.rb.tt
|
|
146
|
+
- lib/generators/openapi_blocks/serializer/serializer_generator.rb
|
|
147
|
+
- lib/generators/openapi_blocks/serializer/templates/serializer.rb.tt
|
|
140
148
|
- lib/openapi_blocks.rb
|
|
149
|
+
- lib/openapi_blocks/auto_serialize.rb
|
|
141
150
|
- lib/openapi_blocks/base.rb
|
|
142
151
|
- lib/openapi_blocks/builder.rb
|
|
143
152
|
- lib/openapi_blocks/cache.rb
|
|
153
|
+
- lib/openapi_blocks/concerns/documentable.rb
|
|
154
|
+
- lib/openapi_blocks/concerns/schemable.rb
|
|
144
155
|
- lib/openapi_blocks/configuration.rb
|
|
145
156
|
- lib/openapi_blocks/configuration/contact_builder.rb
|
|
146
157
|
- lib/openapi_blocks/configuration/info_builder.rb
|
|
@@ -154,12 +165,13 @@ files:
|
|
|
154
165
|
- lib/openapi_blocks/middleware.rb
|
|
155
166
|
- lib/openapi_blocks/operation_builder.rb
|
|
156
167
|
- lib/openapi_blocks/railtie.rb
|
|
157
|
-
- lib/openapi_blocks/
|
|
168
|
+
- lib/openapi_blocks/registry.rb
|
|
158
169
|
- lib/openapi_blocks/routing/extractor.rb
|
|
159
170
|
- lib/openapi_blocks/routing/operation.rb
|
|
160
171
|
- lib/openapi_blocks/schema/extractor.rb
|
|
161
172
|
- lib/openapi_blocks/schema/types.rb
|
|
162
173
|
- lib/openapi_blocks/schema/validator.rb
|
|
174
|
+
- lib/openapi_blocks/serialization.rb
|
|
163
175
|
- lib/openapi_blocks/serializer.rb
|
|
164
176
|
- lib/openapi_blocks/spec/components.rb
|
|
165
177
|
- lib/openapi_blocks/spec/document.rb
|
|
@@ -188,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
188
200
|
- !ruby/object:Gem::Version
|
|
189
201
|
version: '0'
|
|
190
202
|
requirements: []
|
|
191
|
-
rubygems_version: 4.0.
|
|
203
|
+
rubygems_version: 4.0.3
|
|
192
204
|
specification_version: 4
|
|
193
|
-
summary:
|
|
205
|
+
summary: OpenAPI 3.0/3.1 documentation and high-performance serializer for Rails
|
|
194
206
|
test_files: []
|
|
@@ -1,20 +0,0 @@
|
|
|
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
|