oas_rails 0.3.0 → 0.4.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 +9 -0
- data/app/controllers/oas_rails/oas_rails_controller.rb +1 -1
- data/lib/generators/oas_rails/config/templates/oas_rails_initializer.rb +11 -0
- data/lib/oas_rails/builders/content_builder.rb +55 -0
- data/lib/oas_rails/builders/operation_builder.rb +32 -0
- data/lib/oas_rails/builders/parameter_builder.rb +28 -0
- data/lib/oas_rails/builders/parameters_builder.rb +39 -0
- data/lib/oas_rails/builders/path_item_builder.rb +22 -0
- data/lib/oas_rails/builders/request_body_builder.rb +60 -0
- data/lib/oas_rails/builders/response_builder.rb +40 -0
- data/lib/oas_rails/builders/responses_builder.rb +58 -0
- data/lib/oas_rails/configuration.rb +17 -5
- data/lib/oas_rails/extractors/oas_route_extractor.rb +66 -0
- data/lib/oas_rails/extractors/render_response_extractor.rb +11 -36
- data/lib/oas_rails/oas_route.rb +0 -5
- data/lib/oas_rails/spec/components.rb +85 -0
- data/lib/oas_rails/spec/contact.rb +18 -0
- data/lib/oas_rails/spec/hashable.rb +39 -0
- data/lib/oas_rails/{info.rb → spec/info.rb} +30 -24
- data/lib/oas_rails/spec/license.rb +18 -0
- data/lib/oas_rails/spec/media_type.rb +84 -0
- data/lib/oas_rails/spec/operation.rb +25 -0
- data/lib/oas_rails/spec/parameter.rb +34 -0
- data/lib/oas_rails/spec/path_item.rb +33 -0
- data/lib/oas_rails/spec/paths.rb +26 -0
- data/lib/oas_rails/spec/reference.rb +16 -0
- data/lib/oas_rails/spec/request_body.rb +21 -0
- data/lib/oas_rails/spec/response.rb +20 -0
- data/lib/oas_rails/spec/responses.rb +25 -0
- data/lib/oas_rails/spec/server.rb +17 -0
- data/lib/oas_rails/spec/specable.rb +51 -0
- data/lib/oas_rails/spec/specification.rb +50 -0
- data/lib/oas_rails/spec/tag.rb +18 -0
- data/lib/oas_rails/utils.rb +39 -0
- data/lib/oas_rails/version.rb +1 -1
- data/lib/oas_rails.rb +41 -16
- metadata +29 -17
- data/lib/oas_rails/contact.rb +0 -12
- data/lib/oas_rails/license.rb +0 -11
- data/lib/oas_rails/media_type.rb +0 -102
- data/lib/oas_rails/oas_base.rb +0 -30
- data/lib/oas_rails/operation.rb +0 -134
- data/lib/oas_rails/parameter.rb +0 -47
- data/lib/oas_rails/path_item.rb +0 -25
- data/lib/oas_rails/paths.rb +0 -19
- data/lib/oas_rails/request_body.rb +0 -29
- data/lib/oas_rails/response.rb +0 -12
- data/lib/oas_rails/responses.rb +0 -20
- data/lib/oas_rails/server.rb +0 -10
- data/lib/oas_rails/specification.rb +0 -72
- data/lib/oas_rails/tag.rb +0 -17
@@ -0,0 +1,85 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class Components
|
4
|
+
include Specable
|
5
|
+
|
6
|
+
attr_accessor :schemas, :parameters, :security_schemes, :request_bodies, :responses, :headers, :examples, :links, :callbacks
|
7
|
+
|
8
|
+
def initialize(specification)
|
9
|
+
@specification = specification
|
10
|
+
@schemas = {}
|
11
|
+
@parameters = {}
|
12
|
+
@security_schemes = OasRails.config.security_schemas
|
13
|
+
@request_bodies = {}
|
14
|
+
@responses = {}
|
15
|
+
@headers = {}
|
16
|
+
@examples = {}
|
17
|
+
@links = {}
|
18
|
+
@callbacks = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def oas_fields
|
22
|
+
[:request_bodies, :examples, :responses, :schemas, :parameters, :security_schemes]
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_response(response)
|
26
|
+
key = response.hash_key
|
27
|
+
@responses[key] = response unless @responses.key? key
|
28
|
+
|
29
|
+
response_reference(key)
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_parameter(parameter)
|
33
|
+
key = parameter.hash_key
|
34
|
+
@parameters[key] = parameter unless @parameters.key? key
|
35
|
+
|
36
|
+
parameter_reference(key)
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_request_body(request_body)
|
40
|
+
key = request_body.hash_key
|
41
|
+
@request_bodies[key] = request_body unless @request_bodies.key? key
|
42
|
+
|
43
|
+
request_body_reference(key)
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_schema(schema)
|
47
|
+
key = Hashable.generate_hash(schema)
|
48
|
+
@schemas[key] = schema if @schemas[key].nil?
|
49
|
+
|
50
|
+
schema_reference(key)
|
51
|
+
end
|
52
|
+
|
53
|
+
def add_example(example)
|
54
|
+
key = Hashable.generate_hash(example)
|
55
|
+
@examples[key] = example if @examples[key].nil?
|
56
|
+
|
57
|
+
example_reference(key)
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_reference(type, name)
|
61
|
+
"#/components/#{type}/#{name}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def schema_reference(name)
|
65
|
+
Reference.new(create_reference('schemas', name))
|
66
|
+
end
|
67
|
+
|
68
|
+
def response_reference(name)
|
69
|
+
Reference.new(create_reference('responses', name))
|
70
|
+
end
|
71
|
+
|
72
|
+
def parameter_reference(name)
|
73
|
+
Reference.new(create_reference('parameters', name))
|
74
|
+
end
|
75
|
+
|
76
|
+
def example_reference(name)
|
77
|
+
Reference.new(create_reference('examples', name))
|
78
|
+
end
|
79
|
+
|
80
|
+
def request_body_reference(name)
|
81
|
+
Reference.new(create_reference('requestBodies', name))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class Contact
|
4
|
+
include Specable
|
5
|
+
attr_accessor :name, :url, :email
|
6
|
+
|
7
|
+
def initialize(**kwargs)
|
8
|
+
@name = kwargs[:name] || ''
|
9
|
+
@url = kwargs[:url] || ''
|
10
|
+
@email = kwargs[:email] || ''
|
11
|
+
end
|
12
|
+
|
13
|
+
def oas_fields
|
14
|
+
[:name, :url, :email]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
require 'digest'
|
4
|
+
|
5
|
+
module Hashable
|
6
|
+
def hash_key
|
7
|
+
Hashable.generate_hash(hash_representation)
|
8
|
+
end
|
9
|
+
|
10
|
+
def hash_representation
|
11
|
+
public_instance_variables.sort.to_h { |var| [var, instance_variable_get(var)] }
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.generate_hash(obj)
|
15
|
+
Digest::MD5.hexdigest(hash_representation_recursive(obj).to_s)
|
16
|
+
end
|
17
|
+
|
18
|
+
def public_instance_variables
|
19
|
+
instance_variables.select do |var|
|
20
|
+
method_name = var.to_s.delete('@')
|
21
|
+
respond_to?(method_name) || respond_to?("#{method_name}=")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.hash_representation_recursive(obj)
|
26
|
+
case obj
|
27
|
+
when Hash
|
28
|
+
obj.transform_values { |v| hash_representation_recursive(v) }
|
29
|
+
when Array
|
30
|
+
obj.map { |v| hash_representation_recursive(v) }
|
31
|
+
when Hashable
|
32
|
+
obj.hash_representation
|
33
|
+
else
|
34
|
+
obj
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,28 +1,33 @@
|
|
1
1
|
module OasRails
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
2
|
+
module Spec
|
3
|
+
class Info
|
4
|
+
include Specable
|
5
|
+
attr_accessor :title, :summary, :description, :terms_of_service, :contact, :license, :version
|
6
|
+
|
7
|
+
def initialize(**kwargs)
|
8
|
+
@title = kwargs[:title] || default_title
|
9
|
+
@summary = kwargs[:summary] || default_summary
|
10
|
+
@description = kwargs[:description] || default_description
|
11
|
+
@terms_of_service = kwargs[:terms_of_service] || ''
|
12
|
+
@contact = Spec::Contact.new
|
13
|
+
@license = Spec::License.new
|
14
|
+
@version = kwargs[:version] || '0.0.1'
|
15
|
+
end
|
16
|
+
|
17
|
+
def oas_fields
|
18
|
+
[:title, :summary, :description, :terms_of_service, :contact, :license, :version]
|
19
|
+
end
|
20
|
+
|
21
|
+
def default_title
|
22
|
+
"OasRails #{VERSION}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_summary
|
26
|
+
"OasRails: Automatic Interactive API Documentation for Rails"
|
27
|
+
end
|
28
|
+
|
29
|
+
def default_description
|
30
|
+
"# Welcome to OasRails
|
26
31
|
|
27
32
|
OasRails automatically generates interactive documentation for your Rails APIs using the OpenAPI Specification 3.1 (OAS 3.1) and displays it with a nice UI.
|
28
33
|
|
@@ -55,6 +60,7 @@ Explore your API documentation and enjoy the power of OasRails!
|
|
55
60
|
For more information and advanced usage, visit the [OasRails GitHub repository](https://github.com/a-chacon/oas_rails).
|
56
61
|
|
57
62
|
"
|
63
|
+
end
|
58
64
|
end
|
59
65
|
end
|
60
66
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class License
|
4
|
+
include Specable
|
5
|
+
|
6
|
+
attr_accessor :name, :url
|
7
|
+
|
8
|
+
def initialize(**kwargs)
|
9
|
+
@name = kwargs[:name] || 'GPL 3.0'
|
10
|
+
@url = kwargs[:url] || 'https://www.gnu.org/licenses/gpl-3.0.html#license-text'
|
11
|
+
end
|
12
|
+
|
13
|
+
def oas_fields
|
14
|
+
[:name, :url]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class MediaType
|
4
|
+
include Specable
|
5
|
+
|
6
|
+
attr_accessor :schema, :example, :examples, :encoding
|
7
|
+
|
8
|
+
@context = :incoming
|
9
|
+
@factory_examples = {}
|
10
|
+
|
11
|
+
# Initializes a new MediaType object.
|
12
|
+
#
|
13
|
+
# @param schema [Hash] the schema of the media type.
|
14
|
+
# @param kwargs [Hash] additional keyword arguments.
|
15
|
+
def initialize(specification)
|
16
|
+
@specification = specification
|
17
|
+
@schema = {}
|
18
|
+
@example = {}
|
19
|
+
@examples = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def oas_fields
|
23
|
+
[:schema, :example, :examples, :encoding]
|
24
|
+
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
|
+
fixture_data = YAML.load_file(fixture_file).with_indifferent_access
|
72
|
+
rescue Errno::ENOENT
|
73
|
+
return {}
|
74
|
+
end
|
75
|
+
fixture_data.transform_values { |attributes| { value: { klass.to_s.downcase => clean_example_object(obj: attributes) } } }
|
76
|
+
end
|
77
|
+
|
78
|
+
def clean_example_object(obj:)
|
79
|
+
obj.reject { |key, _| OasRails.config.send("excluded_columns_#{@context}").include?(key.to_sym) }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class Operation
|
4
|
+
include Specable
|
5
|
+
|
6
|
+
attr_accessor :specification, :tags, :summary, :description, :operation_id, :parameters, :request_body, :responses, :security
|
7
|
+
|
8
|
+
def initialize(specification)
|
9
|
+
@specification = specification
|
10
|
+
@summary = ""
|
11
|
+
@operation_id = ""
|
12
|
+
@tags = []
|
13
|
+
@description = @summary
|
14
|
+
@parameters = []
|
15
|
+
@request_body = {}
|
16
|
+
@responses = Spec::Responses.new(specification)
|
17
|
+
@security = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def oas_fields
|
21
|
+
[:tags, :summary, :description, :operation_id, :parameters, :request_body, :responses, :security]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class Parameter
|
4
|
+
include Specable
|
5
|
+
include Hashable
|
6
|
+
|
7
|
+
STYLE_DEFAULTS = { query: 'form', path: 'simple', header: 'simple', cookie: 'form' }.freeze
|
8
|
+
|
9
|
+
attr_accessor :name, :in, :style, :description, :required, :schema
|
10
|
+
|
11
|
+
def initialize(specification)
|
12
|
+
@specification = specification
|
13
|
+
@name = ""
|
14
|
+
@in = ""
|
15
|
+
@description = ""
|
16
|
+
@required = false
|
17
|
+
@style = ""
|
18
|
+
@schema = { type: 'string' }
|
19
|
+
end
|
20
|
+
|
21
|
+
def default_from_in
|
22
|
+
STYLE_DEFAULTS[@in.to_sym]
|
23
|
+
end
|
24
|
+
|
25
|
+
def required?
|
26
|
+
@in == 'path'
|
27
|
+
end
|
28
|
+
|
29
|
+
def oas_fields
|
30
|
+
[:name, :in, :description, :required, :schema, :style]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class PathItem
|
4
|
+
include Specable
|
5
|
+
attr_reader :get, :post, :put, :patch, :delete
|
6
|
+
|
7
|
+
def initialize(specification)
|
8
|
+
@specification = specification
|
9
|
+
@get = nil
|
10
|
+
@post = nil
|
11
|
+
@put = nil
|
12
|
+
@patch = nil
|
13
|
+
@delete = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def fill_from(path, route_extractor: Extractors::RouteExtractor)
|
17
|
+
route_extractor.host_routes_by_path(path).each do |oas_route|
|
18
|
+
add_operation(oas_route.verb.downcase, Spec::Operation.new(@specification).fill_from(oas_route))
|
19
|
+
end
|
20
|
+
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_operation(http_method, operation)
|
25
|
+
instance_variable_set("@#{http_method}", operation)
|
26
|
+
end
|
27
|
+
|
28
|
+
def oas_fields
|
29
|
+
[:get, :post, :put, :patch, :delete]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class Paths
|
4
|
+
include Specable
|
5
|
+
|
6
|
+
attr_accessor :path_items
|
7
|
+
|
8
|
+
def initialize(specification)
|
9
|
+
@specification = specification
|
10
|
+
@path_items = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_path(path)
|
14
|
+
@path_items[path] = Builders::PathItemBuilder.new(@specification).from_path(path).build
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_spec
|
18
|
+
paths_hash = {}
|
19
|
+
@path_items.each do |path, path_object|
|
20
|
+
paths_hash[path] = path_object.to_spec
|
21
|
+
end
|
22
|
+
paths_hash
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class RequestBody
|
4
|
+
include Specable
|
5
|
+
include Hashable
|
6
|
+
|
7
|
+
attr_accessor :description, :content, :required
|
8
|
+
|
9
|
+
def initialize(specification)
|
10
|
+
@specification = specification
|
11
|
+
@description = ""
|
12
|
+
@content = {} # a hash with media type objects
|
13
|
+
@required = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def oas_fields
|
17
|
+
[:description, :content, :required]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class Response
|
4
|
+
include Specable
|
5
|
+
include Hashable
|
6
|
+
|
7
|
+
attr_accessor :code, :description, :content
|
8
|
+
|
9
|
+
def initialize(specification)
|
10
|
+
@specification = specification
|
11
|
+
@description = ""
|
12
|
+
@content = {} # Hash with {content: MediaType}
|
13
|
+
end
|
14
|
+
|
15
|
+
def oas_fields
|
16
|
+
[:description, :content]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class Responses
|
4
|
+
include Specable
|
5
|
+
attr_accessor :responses
|
6
|
+
|
7
|
+
def initialize(specification)
|
8
|
+
@specification = specification
|
9
|
+
@responses = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_response(response)
|
13
|
+
@responses[response.code] = @specification.components.add_response(response)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_spec
|
17
|
+
spec = {}
|
18
|
+
@responses.each do |key, value|
|
19
|
+
spec[key] = value.to_spec
|
20
|
+
end
|
21
|
+
spec
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class Server
|
4
|
+
include Specable
|
5
|
+
attr_accessor :url, :description
|
6
|
+
|
7
|
+
def initialize(url:, description:)
|
8
|
+
@url = url
|
9
|
+
@description = description
|
10
|
+
end
|
11
|
+
|
12
|
+
def oas_fields
|
13
|
+
[:url, :description]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
module Specable
|
4
|
+
def oas_fields
|
5
|
+
[]
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_spec
|
9
|
+
hash = {}
|
10
|
+
oas_fields.each do |var|
|
11
|
+
key = var.to_s
|
12
|
+
|
13
|
+
camel_case_key = key.camelize(:lower).to_sym
|
14
|
+
value = send(var)
|
15
|
+
|
16
|
+
processed_value = if value.respond_to?(:to_spec)
|
17
|
+
value.to_spec
|
18
|
+
elsif value.is_a?(Array) && value.all? { |elem| elem.respond_to?(:to_spec) }
|
19
|
+
value.map(&:to_spec)
|
20
|
+
# elsif value.is_a?(Hash)
|
21
|
+
# p "Here"
|
22
|
+
# p value
|
23
|
+
# hash = {}
|
24
|
+
# value.each do |key, object|
|
25
|
+
# hash[key] = object.to_spec
|
26
|
+
# end
|
27
|
+
# hash
|
28
|
+
else
|
29
|
+
value
|
30
|
+
end
|
31
|
+
|
32
|
+
# hash[camel_case_key] = processed_value unless (processed_value.is_a?(Hash) || processed_value.is_a?(Array)) && processed_value.empty?
|
33
|
+
hash[camel_case_key] = processed_value unless processed_value.nil?
|
34
|
+
end
|
35
|
+
hash
|
36
|
+
end
|
37
|
+
|
38
|
+
def as_json
|
39
|
+
to_spec
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def snake_to_camel(snake_str)
|
45
|
+
words = snake_str.to_s.split('_')
|
46
|
+
words[1..].map!(&:capitalize)
|
47
|
+
(words[0] + words[1..].join).to_sym
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module OasRails
|
4
|
+
module Spec
|
5
|
+
class Specification
|
6
|
+
include Specable
|
7
|
+
attr_accessor :components, :info, :openapi, :servers, :tags, :external_docs, :paths
|
8
|
+
|
9
|
+
# Initializes a new Specification object.
|
10
|
+
# Clears the cache if running in the development environment.
|
11
|
+
def initialize
|
12
|
+
clear_cache unless Rails.env.production?
|
13
|
+
|
14
|
+
@components = Components.new(self)
|
15
|
+
@info = OasRails.config.info
|
16
|
+
@openapi = '3.1.0'
|
17
|
+
@servers = OasRails.config.servers
|
18
|
+
@tags = OasRails.config.tags
|
19
|
+
@external_docs = {}
|
20
|
+
@paths = Spec::Paths.new(self)
|
21
|
+
end
|
22
|
+
|
23
|
+
def build(route_extractor: Extractors::RouteExtractor)
|
24
|
+
route_extractor.host_paths.each do |path|
|
25
|
+
@paths.add_path(path)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Clears the cache for MethodSource and RouteExtractor.
|
30
|
+
#
|
31
|
+
# @return [void]
|
32
|
+
def clear_cache
|
33
|
+
MethodSource.clear_cache
|
34
|
+
Extractors::RouteExtractor.clear_cache
|
35
|
+
end
|
36
|
+
|
37
|
+
def oas_fields
|
38
|
+
[:openapi, :info, :servers, :paths, :components, :security, :tags, :external_docs]
|
39
|
+
end
|
40
|
+
|
41
|
+
# Create the Security Requirement Object.
|
42
|
+
# @see https://spec.openapis.org/oas/latest.html#security-requirement-object
|
43
|
+
def security
|
44
|
+
return [] unless OasRails.config.authenticate_all_routes_by_default
|
45
|
+
|
46
|
+
OasRails.config.security_schemas.map { |key, _| { key => [] } }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module OasRails
|
2
|
+
module Spec
|
3
|
+
class Tag
|
4
|
+
include Specable
|
5
|
+
|
6
|
+
attr_accessor :name, :description
|
7
|
+
|
8
|
+
def initialize(name:, description:)
|
9
|
+
@name = name.titleize
|
10
|
+
@description = description
|
11
|
+
end
|
12
|
+
|
13
|
+
def oas_fields
|
14
|
+
[:name, :description]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|