oas_rails 0.13.0 → 0.15.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 +13 -1
- data/lib/oas_rails/active_record_example_finder.rb +65 -0
- data/lib/oas_rails/builders/content_builder.rb +1 -1
- data/lib/oas_rails/builders/oas_route_builder.rb +90 -0
- data/lib/oas_rails/builders/parameters_builder.rb +1 -1
- data/lib/oas_rails/builders/path_item_builder.rb +2 -2
- data/lib/oas_rails/builders/request_body_builder.rb +2 -2
- data/lib/oas_rails/builders/responses_builder.rb +3 -3
- data/lib/oas_rails/configuration.rb +15 -1
- data/lib/oas_rails/extractors/oas_route_extractor.rb +4 -4
- data/lib/oas_rails/extractors/render_response_extractor.rb +2 -2
- data/lib/oas_rails/extractors/route_extractor.rb +3 -3
- data/lib/oas_rails/oas_route.rb +9 -35
- data/lib/oas_rails/spec/media_type.rb +0 -65
- data/lib/oas_rails/spec/path_item.rb +2 -2
- data/lib/oas_rails/spec/specification.rb +3 -3
- data/lib/oas_rails/version.rb +1 -1
- data/lib/oas_rails.rb +2 -0
- metadata +5 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a51597f283e58aada1720795784cf5b6afaf936bd384286674411526b58cb7a2
|
4
|
+
data.tar.gz: 1d595b156bc952b401f5c3d2354eb36e0d4eb0df5f1d3e51f1096f746a160abe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55414ffff2265c00ca787c72533960b2c9c8ac9cc19fb0aa1607c290926d45f60a43bff77af86cb2e26210119228870b1c44c0725626e154cece570473524bc1
|
7
|
+
data.tar.gz: dd19ea6f05ec54ddc606f775e4635d4fccdc459e03cfbf2e1281232faad9dd04ff74f80da4287bae9b8742c2d18bd47d3bd28bf711a0b9c7f6f113c4789a4ab4
|
data/README.md
CHANGED
@@ -9,7 +9,15 @@
|
|
9
9
|
|
10
10
|
OasRails is a Rails engine for generating **automatic interactive documentation for your Rails APIs**. It generates an **OAS 3.1** document and displays it using **[RapiDoc](https://rapidocweb.com)**.
|
11
11
|
|
12
|
-
|
12
|
+
### 🚀 Demo App
|
13
|
+
|
14
|
+
Explore the interactive documentation live:
|
15
|
+
|
16
|
+
🔗 **[Open Demo App](https://paso.fly.dev/api/docs)**
|
17
|
+
👤 **Username**: `oasrails`
|
18
|
+
🔑 **Password**: `oasrails`
|
19
|
+
|
20
|
+
🎬 A Demo Installation/Usage Video:
|
13
21
|
<https://vimeo.com/1013687332>
|
14
22
|
🎬
|
15
23
|
|
@@ -56,3 +64,7 @@ If you plan a big feature, first open an issue to discuss it before any developm
|
|
56
64
|
## License
|
57
65
|
|
58
66
|
The gem is available as open source under the terms of the [GPL-3.0](https://www.gnu.org/licenses/gpl-3.0.en.html#license-text).
|
67
|
+
|
68
|
+
## Star History
|
69
|
+
|
70
|
+
[](https://www.star-history.com/#a-chacon/oas_rails&Date)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module OasRails
|
2
|
+
class ActiveRecordExampleFinder
|
3
|
+
def initialize(context: :incoming, utils: Utils, factory_bot: FactoryBot, erb: ERB, yaml: YAML, file: File)
|
4
|
+
@context = context
|
5
|
+
@utils = utils
|
6
|
+
@factory_bot = factory_bot
|
7
|
+
@erb = erb
|
8
|
+
@yaml = yaml
|
9
|
+
@file = file
|
10
|
+
@factory_examples = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def search(klass)
|
14
|
+
case @utils.detect_test_framework
|
15
|
+
when :factory_bot
|
16
|
+
fetch_factory_bot_examples(klass: klass)
|
17
|
+
when :fixtures
|
18
|
+
fetch_fixture_examples(klass: klass)
|
19
|
+
else
|
20
|
+
{}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Fetches examples from FactoryBot for the provided class.
|
25
|
+
#
|
26
|
+
# @param klass [Class] the class to fetch examples for.
|
27
|
+
# @return [Hash] a hash containing examples data or an empty hash if no examples are found.
|
28
|
+
def fetch_factory_bot_examples(klass:)
|
29
|
+
klass_sym = @utils.class_to_symbol(klass)
|
30
|
+
|
31
|
+
begin
|
32
|
+
@factory_examples[klass_sym] = @factory_bot.build_stubbed_list(klass_sym, 1) if @factory_examples[klass_sym].nil?
|
33
|
+
|
34
|
+
@factory_examples[klass_sym].each_with_index.to_h do |obj, index|
|
35
|
+
["#{klass_sym}#{index + 1}", { value: { klass_sym => clean_example_object(obj: obj.as_json) } }]
|
36
|
+
end.deep_symbolize_keys
|
37
|
+
rescue KeyError
|
38
|
+
{}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Fetches examples from fixtures for the provided class.
|
43
|
+
#
|
44
|
+
# @param klass [Class] the class to fetch examples for.
|
45
|
+
# @return [Hash] a hash containing examples data or an empty hash if no examples are found.
|
46
|
+
def fetch_fixture_examples(klass:)
|
47
|
+
fixture_file = Rails.root.join('test', 'fixtures', "#{klass.to_s.pluralize.downcase}.yml")
|
48
|
+
begin
|
49
|
+
erb_result = @erb.new(@file.read(fixture_file)).result
|
50
|
+
fixture_data = @yaml.safe_load(
|
51
|
+
erb_result,
|
52
|
+
aliases: true,
|
53
|
+
permitted_classes: [Symbol, ActiveSupport::HashWithIndifferentAccess, Time]
|
54
|
+
).with_indifferent_access
|
55
|
+
rescue Errno::ENOENT
|
56
|
+
return {}
|
57
|
+
end
|
58
|
+
fixture_data.transform_values { |attributes| { value: { klass.to_s.downcase => clean_example_object(obj: attributes) } } }.deep_symbolize_keys
|
59
|
+
end
|
60
|
+
|
61
|
+
def clean_example_object(obj:)
|
62
|
+
obj.reject { |key, _| OasRails.config.send("excluded_columns_#{@context}").include?(key.to_sym) }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -38,7 +38,7 @@ module OasRails
|
|
38
38
|
model_schema = Builders::EsquemaBuilder.send("build_#{@context}_schema", klass:)
|
39
39
|
model_schema["required"] = []
|
40
40
|
schema = { type: "object", properties: { klass.to_s.downcase => model_schema } }
|
41
|
-
examples =
|
41
|
+
examples = ActiveRecordExampleFinder.new(context: @context).search(klass)
|
42
42
|
@media_type.schema = @specification.components.add_schema(schema)
|
43
43
|
@media_type.examples = @media_type.examples.merge(examples)
|
44
44
|
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Builders
|
3
|
+
class OasRouteBuilder
|
4
|
+
def self.build_from_rails_route(rails_route)
|
5
|
+
new(rails_route).build
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(rails_route)
|
9
|
+
@rails_route = rails_route
|
10
|
+
end
|
11
|
+
|
12
|
+
def build
|
13
|
+
OasRoute.new(
|
14
|
+
controller_class: controller_class,
|
15
|
+
controller_action: controller_action,
|
16
|
+
controller: controller,
|
17
|
+
controller_path: controller_path,
|
18
|
+
method: method,
|
19
|
+
verb: verb,
|
20
|
+
path: path,
|
21
|
+
rails_route: @rails_route,
|
22
|
+
docstring: docstring,
|
23
|
+
source_string: source_string,
|
24
|
+
tags: tags
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def controller_class
|
31
|
+
"#{@rails_route.defaults[:controller].camelize}Controller"
|
32
|
+
end
|
33
|
+
|
34
|
+
def controller_action
|
35
|
+
"#{controller_class}##{@rails_route.defaults[:action]}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def controller
|
39
|
+
@rails_route.defaults[:controller]
|
40
|
+
end
|
41
|
+
|
42
|
+
def controller_path
|
43
|
+
Rails.root.join("app/controllers/#{controller}_controller.rb").to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
def method
|
47
|
+
@rails_route.defaults[:action]
|
48
|
+
end
|
49
|
+
|
50
|
+
def verb
|
51
|
+
@rails_route.verb
|
52
|
+
end
|
53
|
+
|
54
|
+
def path
|
55
|
+
OasRails.config.route_extractor.clean_route(@rails_route.path.spec.to_s)
|
56
|
+
end
|
57
|
+
|
58
|
+
def source_string
|
59
|
+
controller_class.constantize.instance_method(method).source
|
60
|
+
end
|
61
|
+
|
62
|
+
def docstring
|
63
|
+
comment_lines = controller_class.constantize.instance_method(method).comment.lines
|
64
|
+
processed_lines = comment_lines.map { |line| line.sub(/^# /, '') }
|
65
|
+
|
66
|
+
filtered_lines = processed_lines.reject do |line|
|
67
|
+
line.include?('rubocop') ||
|
68
|
+
line.include?('TODO')
|
69
|
+
end
|
70
|
+
|
71
|
+
::YARD::Docstring.parser.parse(filtered_lines.join).to_docstring
|
72
|
+
end
|
73
|
+
|
74
|
+
def tags
|
75
|
+
method_comment = controller_class.constantize.instance_method(method).comment
|
76
|
+
class_comment = controller_class.constantize.instance_method(method).class_comment
|
77
|
+
|
78
|
+
method_tags = parse_tags(method_comment)
|
79
|
+
class_tags = parse_tags(class_comment)
|
80
|
+
|
81
|
+
method_tags + class_tags
|
82
|
+
end
|
83
|
+
|
84
|
+
def parse_tags(comment)
|
85
|
+
lines = comment.lines.map { |line| line.sub(/^# /, '') }
|
86
|
+
::YARD::Docstring.parser.parse(lines.join).tags
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -7,7 +7,7 @@ module OasRails
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def from_oas_route(oas_route)
|
10
|
-
parameters_from_tags(tags: oas_route.
|
10
|
+
parameters_from_tags(tags: oas_route.tags(:parameter))
|
11
11
|
oas_route.path_params.try(:map) do |p|
|
12
12
|
@parameters << ParameterBuilder.new(@specification).from_path(oas_route.path, p).build unless @parameters.any? { |param| param.name.to_s == p.to_s }
|
13
13
|
end
|
@@ -6,8 +6,8 @@ module OasRails
|
|
6
6
|
@path_item = Spec::PathItem.new(specification)
|
7
7
|
end
|
8
8
|
|
9
|
-
def from_path(path
|
10
|
-
route_extractor.host_routes_by_path(path).each do |oas_route|
|
9
|
+
def from_path(path)
|
10
|
+
OasRails.config.route_extractor.host_routes_by_path(path).each do |oas_route|
|
11
11
|
oas_route.verb.downcase.split("|").each do |v|
|
12
12
|
@path_item.add_operation(v, OperationBuilder.new(@specification).from_oas_route(oas_route).build)
|
13
13
|
end
|
@@ -7,11 +7,11 @@ module OasRails
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def from_oas_route(oas_route)
|
10
|
-
tag_request_body = oas_route.
|
10
|
+
tag_request_body = oas_route.tags(:request_body).first
|
11
11
|
if tag_request_body.nil? && OasRails.config.autodiscover_request_body
|
12
12
|
detect_request_body(oas_route) if %w[create update].include? oas_route.method
|
13
13
|
elsif !tag_request_body.nil?
|
14
|
-
from_tags(tag: tag_request_body, examples_tags: oas_route.
|
14
|
+
from_tags(tag: tag_request_body, examples_tags: oas_route.tags(:request_body_example))
|
15
15
|
end
|
16
16
|
|
17
17
|
self
|
@@ -7,8 +7,8 @@ module OasRails
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def from_oas_route(oas_route)
|
10
|
-
oas_route.
|
11
|
-
content = ContentBuilder.new(@specification, :outgoing).with_schema(tag.schema).with_examples_from_tags(oas_route.
|
10
|
+
oas_route.tags(:response).each do |tag|
|
11
|
+
content = ContentBuilder.new(@specification, :outgoing).with_schema(tag.schema).with_examples_from_tags(oas_route.tags(:response_example).filter { |re| re.code == tag.name }).build
|
12
12
|
response = ResponseBuilder.new(@specification).with_code(tag.name.to_i).with_description(tag.text).with_content(content).build
|
13
13
|
|
14
14
|
@responses.add_response(response)
|
@@ -18,7 +18,7 @@ module OasRails
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def add_autodiscovered_responses(oas_route)
|
21
|
-
return self if !OasRails.config.autodiscover_responses || oas_route.
|
21
|
+
return self if !OasRails.config.autodiscover_responses || oas_route.tags(:response).any?
|
22
22
|
|
23
23
|
new_responses = Extractors::RenderResponseExtractor.extract_responses_from_source(@specification, source: oas_route.source_string)
|
24
24
|
|
@@ -15,7 +15,7 @@ module OasRails
|
|
15
15
|
:use_model_names,
|
16
16
|
:rapidoc_theme
|
17
17
|
|
18
|
-
attr_reader :servers, :tags, :security_schema, :include_mode, :response_body_of_default
|
18
|
+
attr_reader :servers, :tags, :security_schema, :include_mode, :response_body_of_default, :route_extractor
|
19
19
|
|
20
20
|
def initialize
|
21
21
|
@info = Spec::Info.new
|
@@ -38,6 +38,7 @@ module OasRails
|
|
38
38
|
@use_model_names = false
|
39
39
|
@rapidoc_theme = :rails
|
40
40
|
@include_mode = :all
|
41
|
+
@route_extractor = Extractors::RouteExtractor
|
41
42
|
|
42
43
|
@possible_default_responses.each do |response|
|
43
44
|
method_name = "response_body_of_#{response}="
|
@@ -74,6 +75,19 @@ module OasRails
|
|
74
75
|
@tags = value.map { |t| Spec::Tag.new(name: t[:name], description: t[:description]) }
|
75
76
|
end
|
76
77
|
|
78
|
+
def route_extractor=(value)
|
79
|
+
unless value.respond_to?(:host_routes) &&
|
80
|
+
value.respond_to?(:host_routes_by_path) &&
|
81
|
+
value.respond_to?(:clear_cache) &&
|
82
|
+
value.respond_to?(:host_paths) &&
|
83
|
+
value.respond_to?(:clean_route)
|
84
|
+
raise ArgumentError,
|
85
|
+
"Route extractor must have the following methods: host_routes, host_routes_by_path, clear_cache, host_paths, and clean_route"
|
86
|
+
end
|
87
|
+
|
88
|
+
@route_extractor = value
|
89
|
+
end
|
90
|
+
|
77
91
|
def excluded_columns_incoming
|
78
92
|
%i[id created_at updated_at deleted_at]
|
79
93
|
end
|
@@ -2,7 +2,7 @@ module OasRails
|
|
2
2
|
module Extractors
|
3
3
|
module OasRouteExtractor
|
4
4
|
def extract_summary(oas_route:)
|
5
|
-
oas_route.
|
5
|
+
oas_route.tags(:summary).first.try(:text) || generate_crud_name(oas_route.method, oas_route.controller.downcase) || "#{oas_route.verb} #{oas_route.path}"
|
6
6
|
end
|
7
7
|
|
8
8
|
def extract_operation_id(oas_route:)
|
@@ -10,7 +10,7 @@ module OasRails
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def extract_tags(oas_route:)
|
13
|
-
tags = oas_route.
|
13
|
+
tags = oas_route.tags(:tags).first
|
14
14
|
if tags.nil?
|
15
15
|
default_tags(oas_route:)
|
16
16
|
else
|
@@ -30,9 +30,9 @@ module OasRails
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def extract_security(oas_route:)
|
33
|
-
return [] if oas_route.
|
33
|
+
return [] if oas_route.tags(:no_auth).any?
|
34
34
|
|
35
|
-
if (methods = oas_route.
|
35
|
+
if (methods = oas_route.tags(:auth).first)
|
36
36
|
OasRails.config.security_schemas.keys.map { |key| { key => [] } }.select do |schema|
|
37
37
|
methods.types.include?(schema.keys.first.to_s)
|
38
38
|
end
|
@@ -81,7 +81,7 @@ module OasRails
|
|
81
81
|
# @return [Array<Hash, Hash>] An array where the first element is the schema and the second is the examples.
|
82
82
|
def build_singular_model_schema_and_examples(_maybe_a_model, errors, klass, schema)
|
83
83
|
if errors.nil?
|
84
|
-
[schema,
|
84
|
+
[schema, ActiveRecordExampleFinder.new(context: :outgoing).search(klass)]
|
85
85
|
else
|
86
86
|
# TODO: this is not building the real schema.
|
87
87
|
[
|
@@ -110,7 +110,7 @@ module OasRails
|
|
110
110
|
# @param schema [Hash] The schema for the model.
|
111
111
|
# @return [Array<Hash, Hash>] An array where the first element is the schema and the second is the examples.
|
112
112
|
def build_array_model_schema_and_examples(maybe_a_model, klass, schema)
|
113
|
-
examples = { maybe_a_model => { value:
|
113
|
+
examples = { maybe_a_model => { value: ActiveRecordExampleFinder.new(context: :outgoing).search(klass).values.map { |p| p.dig(:value, maybe_a_model.singularize.to_sym) } } }
|
114
114
|
[{ type: "array", items: schema }, examples]
|
115
115
|
end
|
116
116
|
|
@@ -48,10 +48,10 @@ module OasRails
|
|
48
48
|
private
|
49
49
|
|
50
50
|
def extract_host_routes
|
51
|
-
routes = valid_routes.map { |r|
|
51
|
+
routes = valid_routes.map { |r| Builders::OasRouteBuilder.build_from_rails_route(r) }
|
52
52
|
|
53
|
-
routes.select! { |route| route.
|
54
|
-
routes.select! { |route| route.
|
53
|
+
routes.select! { |route| route.tags.any? } if OasRails.config.include_mode == :with_tags
|
54
|
+
routes.select! { |route| route.tags.any? { |t| t.tag_name == "oas_include" } } if OasRails.config.include_mode == :explicit
|
55
55
|
routes
|
56
56
|
end
|
57
57
|
|
data/lib/oas_rails/oas_route.rb
CHANGED
@@ -1,47 +1,21 @@
|
|
1
1
|
module OasRails
|
2
2
|
class OasRoute
|
3
|
-
attr_accessor
|
4
|
-
:rails_route, :docstring, :source_string
|
3
|
+
attr_accessor :controller_class, :controller_action, :controller, :controller_path, :method, :verb, :path,
|
4
|
+
:rails_route, :docstring, :source_string
|
5
|
+
attr_writer :tags
|
5
6
|
|
6
|
-
def initialize
|
7
|
-
|
8
|
-
def self.new_from_rails_route(rails_route: ActionDispatch::Journey::Route)
|
9
|
-
instance = new
|
10
|
-
instance.rails_route = rails_route
|
11
|
-
instance.extract_rails_route_data
|
12
|
-
instance
|
13
|
-
end
|
14
|
-
|
15
|
-
def extract_rails_route_data
|
16
|
-
@controller_action = "#{@rails_route.defaults[:controller].camelize}Controller##{@rails_route.defaults[:action]}"
|
17
|
-
@controller_class = "#{@rails_route.defaults[:controller].camelize}Controller"
|
18
|
-
@controller = @rails_route.defaults[:controller]
|
19
|
-
@controller_path = controller_path_extractor(@rails_route.defaults[:controller])
|
20
|
-
@method = @rails_route.defaults[:action]
|
21
|
-
@verb = @rails_route.verb
|
22
|
-
@path = Extractors::RouteExtractor.clean_route(@rails_route.path.spec.to_s)
|
23
|
-
@docstring = extract_docstring
|
24
|
-
@source_string = extract_source_string
|
25
|
-
end
|
26
|
-
|
27
|
-
def extract_docstring
|
28
|
-
comment_lines = controller_class.constantize.instance_method(method).comment.lines
|
29
|
-
processed_lines = comment_lines.map do |line|
|
30
|
-
line.sub(/^# /, '')
|
31
|
-
end
|
32
|
-
::YARD::Docstring.parser.parse(processed_lines.join).to_docstring
|
33
|
-
end
|
34
|
-
|
35
|
-
def extract_source_string
|
36
|
-
@controller_class.constantize.instance_method(method).source
|
7
|
+
def initialize(attributes = {})
|
8
|
+
attributes.each { |key, value| send("#{key}=", value) }
|
37
9
|
end
|
38
10
|
|
39
11
|
def path_params
|
40
12
|
@rails_route.path.spec.to_s.scan(/:(\w+)/).flatten.reject! { |e| e == 'format' }
|
41
13
|
end
|
42
14
|
|
43
|
-
def
|
44
|
-
|
15
|
+
def tags(name = nil)
|
16
|
+
return @tags if name.nil?
|
17
|
+
|
18
|
+
@tags.select { |tag| tag.tag_name.to_s == name.to_s }
|
45
19
|
end
|
46
20
|
end
|
47
21
|
end
|
@@ -5,9 +5,6 @@ module OasRails
|
|
5
5
|
|
6
6
|
attr_accessor :schema, :example, :examples, :encoding
|
7
7
|
|
8
|
-
@context = :incoming
|
9
|
-
@factory_examples = {}
|
10
|
-
|
11
8
|
# Initializes a new MediaType object.
|
12
9
|
#
|
13
10
|
# @param schema [Hash] the schema of the media type.
|
@@ -22,68 +19,6 @@ module OasRails
|
|
22
19
|
def oas_fields
|
23
20
|
[:schema, :example, :examples, :encoding]
|
24
21
|
end
|
25
|
-
|
26
|
-
class << self
|
27
|
-
# Searches for examples in test files based on the provided class and test framework.
|
28
|
-
#
|
29
|
-
# @param klass [Class] the class to search examples for.
|
30
|
-
# @param utils [Module] a utility module that provides the `detect_test_framework` method. Defaults to `Utils`.
|
31
|
-
# @return [Hash] a hash containing examples data or an empty hash if no examples are found.
|
32
|
-
def search_for_examples_in_tests(klass, context: :incoming, utils: Utils)
|
33
|
-
@context = context
|
34
|
-
case utils.detect_test_framework
|
35
|
-
when :factory_bot
|
36
|
-
fetch_factory_bot_examples(klass:)
|
37
|
-
when :fixtures
|
38
|
-
fetch_fixture_examples(klass:)
|
39
|
-
else
|
40
|
-
{}
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
# Fetches examples from FactoryBot for the provided class.
|
47
|
-
#
|
48
|
-
# @param klass [Class] the class to fetch examples for.
|
49
|
-
# @return [Hash] a hash containing examples data or an empty hash if no examples are found.
|
50
|
-
def fetch_factory_bot_examples(klass:)
|
51
|
-
klass_sym = Utils.class_to_symbol(klass)
|
52
|
-
|
53
|
-
begin
|
54
|
-
@factory_examples[klass_sym] = FactoryBot.build_stubbed_list(klass_sym, 1) if @factory_examples[klass_sym].nil?
|
55
|
-
|
56
|
-
@factory_examples[klass_sym].each_with_index.to_h do |obj, index|
|
57
|
-
["#{klass_sym}#{index + 1}", { value: { klass_sym => clean_example_object(obj: obj.as_json) } }]
|
58
|
-
end
|
59
|
-
rescue KeyError
|
60
|
-
{}
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Fetches examples from fixtures for the provided class.
|
65
|
-
#
|
66
|
-
# @param klass [Class] the class to fetch examples for.
|
67
|
-
# @return [Hash] a hash containing examples data or an empty hash if no examples are found.
|
68
|
-
def fetch_fixture_examples(klass:)
|
69
|
-
fixture_file = Rails.root.join('test', 'fixtures', "#{klass.to_s.pluralize.downcase}.yml")
|
70
|
-
begin
|
71
|
-
erb_result = ERB.new(File.read(fixture_file)).result
|
72
|
-
fixture_data = YAML.safe_load(
|
73
|
-
erb_result,
|
74
|
-
aliases: true,
|
75
|
-
permitted_classes: [Symbol, ActiveSupport::HashWithIndifferentAccess, Time]
|
76
|
-
).with_indifferent_access
|
77
|
-
rescue Errno::ENOENT
|
78
|
-
return {}
|
79
|
-
end
|
80
|
-
fixture_data.transform_values { |attributes| { value: { klass.to_s.downcase => clean_example_object(obj: attributes) } } }
|
81
|
-
end
|
82
|
-
|
83
|
-
def clean_example_object(obj:)
|
84
|
-
obj.reject { |key, _| OasRails.config.send("excluded_columns_#{@context}").include?(key.to_sym) }
|
85
|
-
end
|
86
|
-
end
|
87
22
|
end
|
88
23
|
end
|
89
24
|
end
|
@@ -13,8 +13,8 @@ module OasRails
|
|
13
13
|
@delete = nil
|
14
14
|
end
|
15
15
|
|
16
|
-
def fill_from(path
|
17
|
-
route_extractor.host_routes_by_path(path).each do |oas_route|
|
16
|
+
def fill_from(path)
|
17
|
+
OasRails.config.route_extractor.host_routes_by_path(path).each do |oas_route|
|
18
18
|
add_operation(oas_route.verb.downcase, Spec::Operation.new(@specification).fill_from(oas_route))
|
19
19
|
end
|
20
20
|
|
@@ -20,8 +20,8 @@ module OasRails
|
|
20
20
|
@paths = Spec::Paths.new(self)
|
21
21
|
end
|
22
22
|
|
23
|
-
def build
|
24
|
-
route_extractor.host_paths.each do |path|
|
23
|
+
def build
|
24
|
+
OasRails.config.route_extractor.host_paths.each do |path|
|
25
25
|
@paths.add_path(path)
|
26
26
|
end
|
27
27
|
end
|
@@ -31,7 +31,7 @@ module OasRails
|
|
31
31
|
# @return [void]
|
32
32
|
def clear_cache
|
33
33
|
MethodSource.clear_cache
|
34
|
-
|
34
|
+
OasRails.config.route_extractor.clear_cache
|
35
35
|
end
|
36
36
|
|
37
37
|
def oas_fields
|
data/lib/oas_rails/version.rb
CHANGED
data/lib/oas_rails.rb
CHANGED
@@ -10,6 +10,7 @@ module OasRails
|
|
10
10
|
autoload :OasRoute, "oas_rails/oas_route"
|
11
11
|
autoload :Utils, "oas_rails/utils"
|
12
12
|
autoload :JsonSchemaGenerator, "oas_rails/json_schema_generator"
|
13
|
+
autoload :ActiveRecordExampleFinder, "oas_rails/active_record_example_finder"
|
13
14
|
|
14
15
|
module Builders
|
15
16
|
autoload :OperationBuilder, "oas_rails/builders/operation_builder"
|
@@ -21,6 +22,7 @@ module OasRails
|
|
21
22
|
autoload :ParameterBuilder, "oas_rails/builders/parameter_builder"
|
22
23
|
autoload :RequestBodyBuilder, "oas_rails/builders/request_body_builder"
|
23
24
|
autoload :EsquemaBuilder, "oas_rails/builders/esquema_builder"
|
25
|
+
autoload :OasRouteBuilder, "oas_rails/builders/oas_route_builder"
|
24
26
|
end
|
25
27
|
|
26
28
|
# This module contains all the clases that represent a part of the OAS file.
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oas_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- a-chacon
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: easy_talk_two
|
@@ -80,8 +79,10 @@ files:
|
|
80
79
|
- lib/generators/oas_rails/config/config_generator.rb
|
81
80
|
- lib/generators/oas_rails/config/templates/oas_rails_initializer.rb
|
82
81
|
- lib/oas_rails.rb
|
82
|
+
- lib/oas_rails/active_record_example_finder.rb
|
83
83
|
- lib/oas_rails/builders/content_builder.rb
|
84
84
|
- lib/oas_rails/builders/esquema_builder.rb
|
85
|
+
- lib/oas_rails/builders/oas_route_builder.rb
|
85
86
|
- lib/oas_rails/builders/operation_builder.rb
|
86
87
|
- lib/oas_rails/builders/parameter_builder.rb
|
87
88
|
- lib/oas_rails/builders/parameters_builder.rb
|
@@ -129,7 +130,6 @@ licenses:
|
|
129
130
|
- GPL-3.0-only
|
130
131
|
metadata:
|
131
132
|
homepage_uri: https://github.com/a-chacon/oas_rails
|
132
|
-
post_install_message:
|
133
133
|
rdoc_options: []
|
134
134
|
require_paths:
|
135
135
|
- lib
|
@@ -144,8 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
146
|
requirements: []
|
147
|
-
rubygems_version: 3.
|
148
|
-
signing_key:
|
147
|
+
rubygems_version: 3.6.7
|
149
148
|
specification_version: 4
|
150
149
|
summary: OasRails is a Rails engine for generating automatic interactive documentation
|
151
150
|
for your Rails APIs.
|