oas_rails 0.12.0 → 0.13.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/lib/generators/oas_rails/config/templates/oas_rails_initializer.rb +5 -2
- data/lib/oas_rails/builders/content_builder.rb +1 -1
- data/lib/oas_rails/builders/request_body_builder.rb +1 -1
- data/lib/oas_rails/builders/responses_builder.rb +31 -11
- data/lib/oas_rails/configuration.rb +26 -4
- data/lib/oas_rails/extractors/render_response_extractor.rb +1 -1
- data/lib/oas_rails/json_schema_generator.rb +4 -0
- data/lib/oas_rails/utils.rb +12 -13
- data/lib/oas_rails/version.rb +1 -1
- data/lib/oas_rails/yard/oas_rails_factory.rb +1 -11
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0b32fa577fb8e747811369e952c3508011a6270366784ab3eb0ff69d579c51b
|
4
|
+
data.tar.gz: 251e05d5a07104a8cea8635197dbf110d0749576f383aa38de6ebe7cebf89c06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bcb332e43ce4caa1be24e598589a9fdba1dad280488d9c3a6b3764b0037bba2b484c525f5733bfd26fa77b76ee3f9944c88c6d6fbe3dc6649c33203d1cf9d47
|
7
|
+
data.tar.gz: 4153c860f49b50c870e3ee86382b08fa29686e96aef9f2e39056b4d4f6364617963e6d71a1e48e3bdee25ef7149548c5974986c7884c5ab6be235b642d13a8c0
|
@@ -26,6 +26,8 @@ OasRails.configure do |config|
|
|
26
26
|
|
27
27
|
3. Use Yard tags in your controller methods to provide detailed API endpoint descriptions.
|
28
28
|
|
29
|
+
Docs: <https://a-chacon.com/oas_rails/>
|
30
|
+
|
29
31
|
## Features
|
30
32
|
|
31
33
|
- Automatic OAS 3.1 document generation
|
@@ -105,6 +107,7 @@ OasRails.configure do |config|
|
|
105
107
|
# Example, if you add forbidden then it will be added only if the endpoint requires authentication.
|
106
108
|
# Example: not_found will be setted to the endpoint only if the operation is a show/update/destroy action.
|
107
109
|
# config.set_default_responses = true
|
108
|
-
# config.possible_default_responses = [:not_found, :unauthorized, :forbidden]
|
109
|
-
# config.response_body_of_default = { message: String }
|
110
|
+
# config.possible_default_responses = [:not_found, :unauthorized, :forbidden, :internal_server_error, :unprocessable_entity]
|
111
|
+
# config.response_body_of_default = "Hash{ message: String }"
|
112
|
+
# config.response_body_of_unprocessable_entity= "Hash{ errors: Array<String> }"
|
110
113
|
end
|
@@ -33,7 +33,7 @@ module OasRails
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def from_model_class(klass)
|
36
|
-
return self unless
|
36
|
+
return self unless Utils.active_record_class?(klass)
|
37
37
|
|
38
38
|
model_schema = Builders::EsquemaBuilder.send("build_#{@context}_schema", klass:)
|
39
39
|
model_schema["required"] = []
|
@@ -18,7 +18,7 @@ module OasRails
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def from_tags(tag:, examples_tags: [])
|
21
|
-
if tag.klass
|
21
|
+
if Utils.active_record_class?(tag.klass)
|
22
22
|
from_model_class(klass: tag.klass, description: tag.text, required: tag.required, examples_tags:)
|
23
23
|
else
|
24
24
|
@request_body.description = tag.text
|
@@ -32,29 +32,49 @@ module OasRails
|
|
32
32
|
def add_default_responses(oas_route, security)
|
33
33
|
return self unless OasRails.config.set_default_responses
|
34
34
|
|
35
|
-
|
35
|
+
common_errors = determine_common_errors(oas_route, security)
|
36
|
+
add_responses_for_errors(common_errors)
|
37
|
+
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def build
|
42
|
+
@responses
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def determine_common_errors(oas_route, security)
|
36
48
|
common_errors = []
|
37
|
-
common_errors.push(:unauthorized, :forbidden) if security
|
49
|
+
common_errors.push(:unauthorized, :forbidden, :internal_server_error) if security
|
38
50
|
|
39
51
|
case oas_route.method
|
40
|
-
when "show", "
|
52
|
+
when "show", "destroy"
|
41
53
|
common_errors.push(:not_found)
|
42
|
-
when "create"
|
43
|
-
|
54
|
+
when "create"
|
55
|
+
common_errors.push(:unprocessable_entity)
|
56
|
+
when "update"
|
57
|
+
common_errors.push(:not_found, :unprocessable_entity)
|
44
58
|
end
|
45
59
|
|
46
|
-
|
47
|
-
|
60
|
+
OasRails.config.possible_default_responses & common_errors
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_responses_for_errors(errors)
|
64
|
+
errors.each do |error|
|
65
|
+
response_body = resolve_response_body(error)
|
66
|
+
content = ContentBuilder.new(@specification, :outgoing).with_schema(JsonSchemaGenerator.process_string(response_body)[:json_schema]).build
|
67
|
+
code = Utils.status_to_integer(error)
|
48
68
|
response = ResponseBuilder.new(@specification).with_code(code).with_description(Utils.get_definition(code)).with_content(content).build
|
49
69
|
|
50
70
|
@responses.add_response(response) if @responses.responses[response.code].blank?
|
51
71
|
end
|
52
|
-
|
53
|
-
self
|
54
72
|
end
|
55
73
|
|
56
|
-
def
|
57
|
-
|
74
|
+
def resolve_response_body(error)
|
75
|
+
OasRails.config.public_send("response_body_of_#{error}")
|
76
|
+
rescue StandardError
|
77
|
+
OasRails.config.response_body_of_default
|
58
78
|
end
|
59
79
|
end
|
60
80
|
end
|
@@ -11,12 +11,11 @@ module OasRails
|
|
11
11
|
:authenticate_all_routes_by_default,
|
12
12
|
:set_default_responses,
|
13
13
|
:possible_default_responses,
|
14
|
-
:response_body_of_default,
|
15
14
|
:http_verbs,
|
16
15
|
:use_model_names,
|
17
16
|
:rapidoc_theme
|
18
17
|
|
19
|
-
attr_reader :servers, :tags, :security_schema, :include_mode
|
18
|
+
attr_reader :servers, :tags, :security_schema, :include_mode, :response_body_of_default
|
20
19
|
|
21
20
|
def initialize
|
22
21
|
@info = Spec::Info.new
|
@@ -33,12 +32,28 @@ module OasRails
|
|
33
32
|
@security_schema = nil
|
34
33
|
@security_schemas = {}
|
35
34
|
@set_default_responses = true
|
36
|
-
@possible_default_responses = [:not_found, :unauthorized, :forbidden]
|
35
|
+
@possible_default_responses = [:not_found, :unauthorized, :forbidden, :internal_server_error, :unprocessable_entity]
|
37
36
|
@http_verbs = [:get, :post, :put, :patch, :delete]
|
38
|
-
@response_body_of_default = "Hash{
|
37
|
+
@response_body_of_default = "Hash{ status: !Integer, error: String }"
|
39
38
|
@use_model_names = false
|
40
39
|
@rapidoc_theme = :rails
|
41
40
|
@include_mode = :all
|
41
|
+
|
42
|
+
@possible_default_responses.each do |response|
|
43
|
+
method_name = "response_body_of_#{response}="
|
44
|
+
variable_name = "@response_body_of_#{response}"
|
45
|
+
|
46
|
+
define_singleton_method(method_name) do |value|
|
47
|
+
raise ArgumentError, "#{method_name} must be a String With a valid object" unless value.is_a?(String)
|
48
|
+
|
49
|
+
OasRails::JsonSchemaGenerator.parse_type(value)
|
50
|
+
instance_variable_set(variable_name, value)
|
51
|
+
end
|
52
|
+
|
53
|
+
define_singleton_method("response_body_of_#{response}") do
|
54
|
+
instance_variable_get(variable_name) || @response_body_of_default
|
55
|
+
end
|
56
|
+
end
|
42
57
|
end
|
43
58
|
|
44
59
|
def security_schema=(value)
|
@@ -73,6 +88,13 @@ module OasRails
|
|
73
88
|
|
74
89
|
@include_mode = value
|
75
90
|
end
|
91
|
+
|
92
|
+
def response_body_of_default=(value)
|
93
|
+
raise ArgumentError, "response_body_of_default must be a String With a valid object" unless value.is_a?(String)
|
94
|
+
|
95
|
+
OasRails::JsonSchemaGenerator.parse_type(value)
|
96
|
+
@response_body_of_default = value
|
97
|
+
end
|
76
98
|
end
|
77
99
|
|
78
100
|
DEFAULT_SECURITY_SCHEMES = {
|
@@ -60,7 +60,7 @@ module OasRails
|
|
60
60
|
maybe_a_model, errors = content.gsub('@', "").split(".")
|
61
61
|
klass = maybe_a_model.singularize.camelize(:upper).constantize
|
62
62
|
|
63
|
-
if
|
63
|
+
if Utils.active_record_class?(klass)
|
64
64
|
schema = Builders::EsquemaBuilder.build_outgoing_schema(klass:)
|
65
65
|
if test_singularity(maybe_a_model)
|
66
66
|
build_singular_model_schema_and_examples(maybe_a_model, errors, klass, schema)
|
@@ -29,6 +29,8 @@ module OasRails
|
|
29
29
|
{ type: :object, required:, properties: parse_object_properties(::Regexp.last_match(1)) }
|
30
30
|
when /^Array<(.+)>$/i
|
31
31
|
{ type: :array, required:, items: parse_type(::Regexp.last_match(1)) }
|
32
|
+
when ->(t) { Utils.active_record_class?(t) }
|
33
|
+
Builders::EsquemaBuilder.build_outgoing_schema(klass: type.constantize)
|
32
34
|
else
|
33
35
|
{ type: type.downcase.to_sym, required: }
|
34
36
|
end
|
@@ -100,6 +102,8 @@ module OasRails
|
|
100
102
|
type: 'array',
|
101
103
|
items: to_json_schema(parsed[:items])
|
102
104
|
}
|
105
|
+
when nil
|
106
|
+
parsed
|
103
107
|
else
|
104
108
|
ruby_type_to_json_schema_type(parsed[:type])
|
105
109
|
end
|
data/lib/oas_rails/utils.rb
CHANGED
@@ -14,6 +14,8 @@ module OasRails
|
|
14
14
|
}.freeze
|
15
15
|
|
16
16
|
HTTP_STATUS_DEFINITIONS = {
|
17
|
+
200 => "The request has succeeded.",
|
18
|
+
201 => "The request has been fulfilled and resulted in a new resource being created.",
|
17
19
|
404 => "The requested resource could not be found.",
|
18
20
|
401 => "You are not authorized to access this resource. You need to authenticate yourself first.",
|
19
21
|
403 => "You are not allowed to access this resource. You do not have the necessary permissions.",
|
@@ -34,19 +36,6 @@ module OasRails
|
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
37
|
-
# TODO: check if it is in use
|
38
|
-
def type_to_schema(type_string)
|
39
|
-
if type_string.start_with?('Array<')
|
40
|
-
inner_type = type_string[/Array<(.+)>$/, 1]
|
41
|
-
{
|
42
|
-
"type" => "array",
|
43
|
-
"items" => type_to_schema(inner_type)
|
44
|
-
}
|
45
|
-
else
|
46
|
-
{ "type" => TYPE_MAPPING.fetch(type_string, 'string') }
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
39
|
def hash_to_json_schema(hash)
|
51
40
|
{
|
52
41
|
type: 'object',
|
@@ -116,6 +105,16 @@ module OasRails
|
|
116
105
|
|
117
106
|
nil # Return nil if no matching constant is found
|
118
107
|
end
|
108
|
+
|
109
|
+
# Checks if a given text refers to an ActiveRecord class.
|
110
|
+
# @param text [String] The text to check.
|
111
|
+
# @return [Boolean] True if the text refers to an ActiveRecord class, false otherwise.
|
112
|
+
def active_record_class?(klass_or_string)
|
113
|
+
klass = klass_or_string.is_a?(Class) ? klass_or_string : klass_or_string.constantize
|
114
|
+
klass.ancestors.map(&:to_s).include? 'ActiveRecord::Base'
|
115
|
+
rescue StandardError
|
116
|
+
false
|
117
|
+
end
|
119
118
|
end
|
120
119
|
end
|
121
120
|
end
|
data/lib/oas_rails/version.rb
CHANGED
@@ -147,23 +147,13 @@ module OasRails
|
|
147
147
|
match
|
148
148
|
end
|
149
149
|
|
150
|
-
# Checks if a given text refers to an ActiveRecord class.
|
151
|
-
# @param text [String] The text to check.
|
152
|
-
# @return [Boolean] True if the text refers to an ActiveRecord class, false otherwise.
|
153
|
-
def active_record_class?(text)
|
154
|
-
klass = text.constantize
|
155
|
-
klass.ancestors.map(&:to_s).include? 'ActiveRecord::Base'
|
156
|
-
rescue StandardError
|
157
|
-
false
|
158
|
-
end
|
159
|
-
|
160
150
|
# Converts type text to a schema, checking if it's an ActiveRecord class.
|
161
151
|
# @param text [String] The type text to convert.
|
162
152
|
# @return [Array] An array containing the class, schema, and required flag.
|
163
153
|
def type_text_to_schema(text)
|
164
154
|
type_text, required = text_and_required(text)
|
165
155
|
|
166
|
-
if active_record_class?(type_text)
|
156
|
+
if Utils.active_record_class?(type_text)
|
167
157
|
klass = type_text.constantize
|
168
158
|
schema = Builders::EsquemaBuilder.build_outgoing_schema(klass:)
|
169
159
|
else
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oas_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- a-chacon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-04-
|
11
|
+
date: 2025-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: easy_talk_two
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.1.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.1.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: method_source
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|