apipie-rails 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +75 -0
- data/.rubocop_todo.yml +780 -201
- data/CHANGELOG.md +8 -0
- data/app/controllers/apipie/apipies_controller.rb +5 -6
- data/lib/apipie/apipie_module.rb +2 -2
- data/lib/apipie/application.rb +6 -6
- data/lib/apipie/configuration.rb +11 -11
- data/lib/apipie/dsl_definition.rb +11 -10
- data/lib/apipie/error_description.rb +2 -2
- data/lib/apipie/extractor/writer.rb +11 -11
- data/lib/apipie/generator/swagger/context.rb +27 -0
- data/lib/apipie/generator/swagger/operation_id.rb +51 -0
- data/lib/apipie/generator/swagger/param_description/builder.rb +105 -0
- data/lib/apipie/generator/swagger/param_description/composite.rb +111 -0
- data/lib/apipie/generator/swagger/param_description/description.rb +15 -0
- data/lib/apipie/generator/swagger/param_description/in.rb +37 -0
- data/lib/apipie/generator/swagger/param_description/name.rb +18 -0
- data/lib/apipie/generator/swagger/param_description/type.rb +108 -0
- data/lib/apipie/generator/swagger/param_description.rb +18 -0
- data/lib/apipie/generator/swagger/type_extractor.rb +2 -2
- data/lib/apipie/method_description.rb +4 -5
- data/lib/apipie/param_description.rb +7 -7
- data/lib/apipie/resource_description.rb +3 -3
- data/lib/apipie/response_description.rb +2 -2
- data/lib/apipie/response_description_adapter.rb +7 -5
- data/lib/apipie/swagger_generator.rb +54 -202
- data/lib/apipie/validator.rb +3 -3
- data/lib/apipie/version.rb +1 -1
- data/lib/apipie-rails.rb +9 -0
- data/lib/tasks/apipie.rake +5 -6
- data/spec/controllers/users_controller_spec.rb +3 -2
- data/spec/lib/generator/swagger/context_spec.rb +35 -0
- data/spec/lib/generator/swagger/operation_id_spec.rb +63 -0
- data/spec/lib/generator/swagger/param_description/builder_spec.rb +163 -0
- data/spec/lib/generator/swagger/param_description/composite_spec.rb +95 -0
- data/spec/lib/generator/swagger/param_description/description_spec.rb +79 -0
- data/spec/lib/generator/swagger/param_description/in_spec.rb +86 -0
- data/spec/lib/generator/swagger/param_description/name_spec.rb +81 -0
- data/spec/lib/generator/swagger/param_description/type_spec.rb +178 -0
- data/spec/lib/generator/swagger/param_description_spec.rb +28 -0
- data/spec/lib/generator/swagger/type_extractor_spec.rb +38 -18
- data/spec/lib/param_group_spec.rb +5 -5
- metadata +20 -2
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,14 @@
|
|
4
4
|
Also deleted the `Gemfile` that was now a broken symlink.
|
5
5
|
please use `export BUNDLE_GEMFILE='gemfiles/Gemfile.rails61'; bundle exec rspec` to run the test suite
|
6
6
|
|
7
|
+
## [v0.9.2](https://github.com/Apipie/apipie-rails/tree/v0.9.2) (2023-02-07)
|
8
|
+
[Full Changelog](https://github.com/Apipie/apipie-rails/compare/v0.9.1...v0.9.2)
|
9
|
+
* [Rubocop] More Rubocop Auto corrections [#795](https://github.com/Apipie/apipie-rails/pull/795)[#781](https://github.com/Apipie/apipie-rails/pull/781)[#791](https://github.com/Apipie/apipie-rails/pull/791)[#788](https://github.com/Apipie/apipie-rails/pull/788) (Rubocop Challenger)
|
10
|
+
* [Fix] Can't include translation in full description ([#446](https://github.com/Apipie/apipie-rails/issues/446)) [#808](https://github.com/Apipie/apipie-rails/pull/808)( Peter Nagy)
|
11
|
+
* [Refactor] Move swagger param description creation [#810](https://github.com/Apipie/apipie-rails/pull/810) (Panos Dalitsouris)
|
12
|
+
* [Rubocop] Redo rubocop TODOs, set HashSyntax config to most used style [#814](https://github.com/Apipie/apipie-rails/pull/814) (Mathieu Jobin)
|
13
|
+
* [Fix] Swagger missing i18n [#815](https://github.com/Apipie/apipie-rails/pull/815) (@jirubio)
|
14
|
+
|
7
15
|
## [v0.9.1](https://github.com/Apipie/apipie-rails/tree/v0.9.1) (2023-01-16)
|
8
16
|
[Full Changelog](https://github.com/Apipie/apipie-rails/compare/v0.9.0...v0.9.1)
|
9
17
|
* [Refactor] Create test cache files under a not version controlled directory [#809](https://github.com/Apipie/apipie-rails/pull/809) (Panos Dalitsouris)
|
@@ -98,12 +98,11 @@ module Apipie
|
|
98
98
|
return nil unless Apipie.configuration.translate
|
99
99
|
lang = Apipie.configuration.default_locale
|
100
100
|
[:resource, :method, :version].each do |par|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
101
|
+
next unless params[par]
|
102
|
+
splitted = params[par].split('.')
|
103
|
+
if splitted.length > 1 && (Apipie.configuration.languages.include?(splitted.last) || Apipie.configuration.default_locale == splitted.last)
|
104
|
+
lang = splitted.last
|
105
|
+
params[par].sub!(".#{lang}", '')
|
107
106
|
end
|
108
107
|
end
|
109
108
|
lang
|
data/lib/apipie/apipie_module.rb
CHANGED
@@ -70,11 +70,11 @@ module Apipie
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def self.app_info_version_valid?(version)
|
73
|
-
version && self.configuration.app_info.
|
73
|
+
version && self.configuration.app_info.key?(version)
|
74
74
|
end
|
75
75
|
|
76
76
|
def self.api_base_url_version_valid?(version)
|
77
|
-
version && self.configuration.api_base_url.
|
77
|
+
version && self.configuration.api_base_url.key?(version)
|
78
78
|
end
|
79
79
|
|
80
80
|
def self.record(record)
|
data/lib/apipie/application.rb
CHANGED
@@ -147,7 +147,7 @@ module Apipie
|
|
147
147
|
|
148
148
|
def get_param_group(controller, name)
|
149
149
|
key = "#{controller.name}##{name}"
|
150
|
-
if @param_groups.
|
150
|
+
if @param_groups.key?(key)
|
151
151
|
return @param_groups[key]
|
152
152
|
else
|
153
153
|
raise "param group #{key} not defined"
|
@@ -185,7 +185,7 @@ module Apipie
|
|
185
185
|
resource_description.method_description(method_name.to_sym)
|
186
186
|
end
|
187
187
|
end
|
188
|
-
alias
|
188
|
+
alias [] get_method_description
|
189
189
|
|
190
190
|
# options:
|
191
191
|
# => "users"
|
@@ -198,7 +198,7 @@ module Apipie
|
|
198
198
|
version = crumbs.first
|
199
199
|
end
|
200
200
|
version ||= Apipie.configuration.default_version
|
201
|
-
if @resource_descriptions.
|
201
|
+
if @resource_descriptions.key?(version)
|
202
202
|
return @resource_descriptions[version][crumbs.last]
|
203
203
|
end
|
204
204
|
else
|
@@ -373,7 +373,7 @@ module Apipie
|
|
373
373
|
def get_resource_name(klass)
|
374
374
|
if klass.class == String
|
375
375
|
klass
|
376
|
-
elsif @controller_to_resource_id.
|
376
|
+
elsif @controller_to_resource_id.key?(klass)
|
377
377
|
@controller_to_resource_id[klass]
|
378
378
|
elsif Apipie.configuration.namespaced_resources? && klass.respond_to?(:controller_path)
|
379
379
|
return nil if klass == ActionController::Base
|
@@ -408,9 +408,9 @@ module Apipie
|
|
408
408
|
# Make sure that the version/resource_name/method_name are valid combination
|
409
409
|
# resource_name and method_name can be nil
|
410
410
|
def valid_search_args?(version, resource_name, method_name)
|
411
|
-
return false unless self.resource_descriptions.
|
411
|
+
return false unless self.resource_descriptions.key?(version)
|
412
412
|
if resource_name
|
413
|
-
return false unless self.resource_descriptions[version].
|
413
|
+
return false unless self.resource_descriptions[version].key?(resource_name)
|
414
414
|
if method_name
|
415
415
|
resource_description = self.resource_descriptions[version][resource_name]
|
416
416
|
return false unless resource_description.valid_method_name?(method_name)
|
data/lib/apipie/configuration.rb
CHANGED
@@ -14,13 +14,13 @@ module Apipie
|
|
14
14
|
:swagger_allow_additional_properties_in_response, :swagger_responses_use_refs,
|
15
15
|
:swagger_schemes, :swagger_security_definitions, :swagger_global_security
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
alias validate? validate
|
18
|
+
alias required_by_default? required_by_default
|
19
|
+
alias namespaced_resources? namespaced_resources
|
20
|
+
alias swagger_include_warning_tags? swagger_include_warning_tags
|
21
|
+
alias swagger_json_input_uses_refs? swagger_json_input_uses_refs
|
22
|
+
alias swagger_responses_use_refs? swagger_responses_use_refs
|
23
|
+
alias swagger_generate_x_computed_id_field? swagger_generate_x_computed_id_field
|
24
24
|
|
25
25
|
# matcher to be used in Dir.glob to find controllers to be reloaded e.g.
|
26
26
|
#
|
@@ -51,17 +51,17 @@ module Apipie
|
|
51
51
|
def validate_value
|
52
52
|
return (validate? && @validate_value)
|
53
53
|
end
|
54
|
-
|
54
|
+
alias validate_value? validate_value
|
55
55
|
|
56
56
|
def validate_presence
|
57
57
|
return (validate? && @validate_presence)
|
58
58
|
end
|
59
|
-
|
59
|
+
alias validate_presence? validate_presence
|
60
60
|
|
61
61
|
def validate_key
|
62
62
|
return (validate? && @validate_key)
|
63
63
|
end
|
64
|
-
|
64
|
+
alias validate_key? validate_key
|
65
65
|
|
66
66
|
def process_value?
|
67
67
|
@process_params
|
@@ -73,7 +73,7 @@ module Apipie
|
|
73
73
|
#
|
74
74
|
# rake apipie:cache
|
75
75
|
attr_accessor :use_cache
|
76
|
-
|
76
|
+
alias use_cache? use_cache
|
77
77
|
|
78
78
|
attr_writer :cache_dir
|
79
79
|
def cache_dir
|
@@ -70,7 +70,7 @@ module Apipie
|
|
70
70
|
def short(short)
|
71
71
|
_apipie_dsl_data[:short_description] = short
|
72
72
|
end
|
73
|
-
alias
|
73
|
+
alias short_description short
|
74
74
|
|
75
75
|
def path(path)
|
76
76
|
_apipie_dsl_data[:path] = path
|
@@ -160,7 +160,7 @@ module Apipie
|
|
160
160
|
def api_versions(*versions)
|
161
161
|
_apipie_dsl_data[:api_versions].concat(versions)
|
162
162
|
end
|
163
|
-
alias
|
163
|
+
alias api_version api_versions
|
164
164
|
|
165
165
|
# Describe the next method.
|
166
166
|
#
|
@@ -177,8 +177,8 @@ module Apipie
|
|
177
177
|
end
|
178
178
|
_apipie_dsl_data[:description] = description
|
179
179
|
end
|
180
|
-
alias
|
181
|
-
alias
|
180
|
+
alias description desc
|
181
|
+
alias full_description desc
|
182
182
|
|
183
183
|
# describe next method with document in given path
|
184
184
|
# in convension, these doc located under "#{Rails.root}/doc"
|
@@ -246,14 +246,14 @@ module Apipie
|
|
246
246
|
if Apipie.configuration.validate_presence?
|
247
247
|
method_params.each do |_, param|
|
248
248
|
# check if required parameters are present
|
249
|
-
raise ParamMissing.new(param) if param.required && !params.
|
249
|
+
raise ParamMissing.new(param) if param.required && !params.key?(param.name)
|
250
250
|
end
|
251
251
|
end
|
252
252
|
|
253
253
|
if Apipie.configuration.validate_value?
|
254
254
|
method_params.each do |_, param|
|
255
255
|
# params validations
|
256
|
-
param.validate(params[:"#{param.name}"]) if params.
|
256
|
+
param.validate(params[:"#{param.name}"]) if params.key?(param.name)
|
257
257
|
end
|
258
258
|
end
|
259
259
|
|
@@ -272,7 +272,7 @@ module Apipie
|
|
272
272
|
@api_params ||= {}
|
273
273
|
method_params.each do |_, param|
|
274
274
|
# params processing
|
275
|
-
@api_params[param.as] = param.process_value(params[:"#{param.name}"]) if params.
|
275
|
+
@api_params[param.as] = param.process_value(params[:"#{param.name}"]) if params.key?(param.name)
|
276
276
|
end
|
277
277
|
end
|
278
278
|
end
|
@@ -293,9 +293,10 @@ module Apipie
|
|
293
293
|
end
|
294
294
|
|
295
295
|
def _apipie_handle_validate_key_error params, param
|
296
|
-
|
296
|
+
case Apipie.configuration.action_on_non_validated_keys
|
297
|
+
when :raise
|
297
298
|
raise UnknownParam, param
|
298
|
-
|
299
|
+
when :skip
|
299
300
|
params.delete(param)
|
300
301
|
Rails.logger.warn(UnknownParam.new(param).to_s)
|
301
302
|
end
|
@@ -525,7 +526,7 @@ module Apipie
|
|
525
526
|
end
|
526
527
|
end
|
527
528
|
# backwards compatibility
|
528
|
-
|
529
|
+
alias apipie_update_params apipie_update_methods
|
529
530
|
|
530
531
|
def _apipie_concern_subst
|
531
532
|
@_apipie_concern_subst ||= {:controller_path => self.controller_path,
|
@@ -103,7 +103,7 @@ module Apipie
|
|
103
103
|
call = call.stringify_keys
|
104
104
|
ordered_call = OrderedHash.new
|
105
105
|
%w[title verb path versions query request_data response_data code show_in_doc recorded].each do |k|
|
106
|
-
next unless call.
|
106
|
+
next unless call.key?(k)
|
107
107
|
ordered_call[k] = case call[k]
|
108
108
|
when ActiveSupport::HashWithIndifferentAccess
|
109
109
|
convert_file_value(call[k]).to_hash
|
@@ -116,9 +116,10 @@ module Apipie
|
|
116
116
|
|
117
117
|
def convert_file_value hash
|
118
118
|
hash.each do |k, v|
|
119
|
-
|
119
|
+
case v
|
120
|
+
when Rack::Test::UploadedFile, ActionDispatch::Http::UploadedFile
|
120
121
|
hash[k] = "<FILE CONTENT '#{v.original_filename}'>"
|
121
|
-
|
122
|
+
when Hash
|
122
123
|
hash[k] = convert_file_value(v)
|
123
124
|
end
|
124
125
|
end
|
@@ -134,8 +135,8 @@ module Apipie
|
|
134
135
|
old_examples = self.load_recorded_examples
|
135
136
|
merged_examples = []
|
136
137
|
(new_examples.keys + old_examples.keys).uniq.each do |key|
|
137
|
-
if new_examples.
|
138
|
-
if old_examples.
|
138
|
+
if new_examples.key?(key)
|
139
|
+
if old_examples.key?(key)
|
139
140
|
records = deep_merge_examples(new_examples[key], old_examples[key])
|
140
141
|
else
|
141
142
|
records = new_examples[key]
|
@@ -407,12 +408,11 @@ module Apipie
|
|
407
408
|
if line =~ /\s*\b(module|class|def)\b /
|
408
409
|
break
|
409
410
|
end
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
end
|
411
|
+
next unless line =~ /do\s*(\|.*?\|)?\s*$/
|
412
|
+
block_level -= 1
|
413
|
+
if block_level == 0
|
414
|
+
added_lines.concat(lines_to_add)
|
415
|
+
lines_to_add = []
|
416
416
|
end
|
417
417
|
end
|
418
418
|
return added_lines.reverse.join
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Apipie::Generator::Swagger::Context
|
2
|
+
attr_reader :default_in_value, :language, :http_method, :controller_method
|
3
|
+
|
4
|
+
def initialize(
|
5
|
+
allow_null:,
|
6
|
+
http_method:,
|
7
|
+
controller_method:,
|
8
|
+
default_in_value: nil,
|
9
|
+
language: nil,
|
10
|
+
in_schema: true
|
11
|
+
)
|
12
|
+
@default_in_value = default_in_value
|
13
|
+
@allow_null = allow_null
|
14
|
+
@language = language
|
15
|
+
@in_schema = in_schema
|
16
|
+
@http_method = http_method
|
17
|
+
@controller_method = controller_method
|
18
|
+
end
|
19
|
+
|
20
|
+
def allow_null?
|
21
|
+
@allow_null == true
|
22
|
+
end
|
23
|
+
|
24
|
+
def in_schema?
|
25
|
+
@in_schema == true
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class Apipie::Generator::Swagger::OperationId
|
2
|
+
def initialize(path:, http_method:, param: nil)
|
3
|
+
@path = path
|
4
|
+
@http_method = http_method
|
5
|
+
@param = param
|
6
|
+
end
|
7
|
+
|
8
|
+
# @return [String]
|
9
|
+
def to_s
|
10
|
+
base = normalized_http_method + path
|
11
|
+
|
12
|
+
if @param.present?
|
13
|
+
"#{base}_param_#{@param}"
|
14
|
+
else
|
15
|
+
base
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param [Apipie::MethodDescription::Api, Apipie::MethodDescription] describable
|
20
|
+
# @param [String, Symbol, nil] param
|
21
|
+
#
|
22
|
+
# @return [Apipie::Generator::Swagger::OperationId]
|
23
|
+
def self.from(describable, param: nil)
|
24
|
+
path, http_method =
|
25
|
+
if describable.is_a?(Apipie::MethodDescription::Api)
|
26
|
+
[describable.path, describable.http_method]
|
27
|
+
elsif describable.is_a?(Apipie::MethodDescription)
|
28
|
+
[describable.apis.first.path, describable.apis.first.http_method]
|
29
|
+
end
|
30
|
+
|
31
|
+
new(path: path, http_method: http_method, param: param)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Converts an http path for example `/api/concerns/:id` to `_api_concerns_id`
|
37
|
+
#
|
38
|
+
# @return [String]
|
39
|
+
def path
|
40
|
+
@path.gsub(/\//, '_').gsub(/:(\w+)/, '\1').gsub(/_$/, '')
|
41
|
+
end
|
42
|
+
|
43
|
+
# Converts an http method like `GET` to `get` Using lowercase http method,
|
44
|
+
# because the 'swagger-codegen' tool outputs strange method names if the
|
45
|
+
# http method is in uppercase
|
46
|
+
#
|
47
|
+
# @return [String]
|
48
|
+
def normalized_http_method
|
49
|
+
@http_method.to_s.downcase
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
class Apipie::Generator::Swagger::ParamDescription::Builder
|
2
|
+
# @param [Apipie::ParamDescription] param_description
|
3
|
+
# @param [TrueClass, FalseClass] in_schema
|
4
|
+
# @param [String] controller_method
|
5
|
+
def initialize(param_description, in_schema:, controller_method:)
|
6
|
+
@param_description = param_description
|
7
|
+
@in_schema = in_schema
|
8
|
+
@controller_method = controller_method
|
9
|
+
end
|
10
|
+
|
11
|
+
# @param [String, nil] prefix
|
12
|
+
def with_name(prefix: nil)
|
13
|
+
@name = Apipie::Generator::Swagger::ParamDescription::Name.
|
14
|
+
new(@param_description, prefixed_by: prefix)
|
15
|
+
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param [String] language
|
20
|
+
def with_description(language:)
|
21
|
+
@description = Apipie::Generator::Swagger::ParamDescription::Description.
|
22
|
+
new(@param_description, language: language)
|
23
|
+
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param [TrueClass, FalseClass] with_null
|
28
|
+
def with_type(with_null:)
|
29
|
+
@type = Apipie::Generator::Swagger::ParamDescription::Type.
|
30
|
+
new(@param_description, with_null: with_null, controller_method: @controller_method)
|
31
|
+
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def with_in(http_method:, default_in_value: nil)
|
36
|
+
@in = Apipie::Generator::Swagger::ParamDescription::In.new(
|
37
|
+
@param_description,
|
38
|
+
in_schema: @in_schema,
|
39
|
+
default_in_value: default_in_value,
|
40
|
+
http_method: http_method
|
41
|
+
)
|
42
|
+
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Hash]
|
47
|
+
def to_swagger
|
48
|
+
definition = {}
|
49
|
+
|
50
|
+
definition.merge!(@name.to_hash) if @name.present?
|
51
|
+
definition.merge!(@type.to_hash) if @type.present?
|
52
|
+
definition.merge!(@in.to_hash) if @in.present?
|
53
|
+
|
54
|
+
definition.merge!(for_default)
|
55
|
+
definition.merge!(for_required)
|
56
|
+
definition.merge!(@description.to_hash) if @description.present?
|
57
|
+
|
58
|
+
warn_optional_without_default_value(definition)
|
59
|
+
|
60
|
+
definition
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def for_required
|
66
|
+
return {} if !required?
|
67
|
+
|
68
|
+
{
|
69
|
+
required: true
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
def for_default
|
74
|
+
return {} if @param_description.options[:default_value].blank?
|
75
|
+
|
76
|
+
{
|
77
|
+
default: @param_description.options[:default_value],
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
def required?
|
82
|
+
required_from_path? || (!@in_schema && @param_description.required)
|
83
|
+
end
|
84
|
+
|
85
|
+
def required_from_path?
|
86
|
+
@param_description.options[:added_from_path] == true
|
87
|
+
end
|
88
|
+
|
89
|
+
def warn_optional_without_default_value(definition)
|
90
|
+
if !required? && !definition.key?(:default)
|
91
|
+
method =
|
92
|
+
if @param_description.is_a?(Apipie::ResponseDescriptionAdapter::PropDesc)
|
93
|
+
@controller_method
|
94
|
+
else
|
95
|
+
@param_description.method_description.method
|
96
|
+
end
|
97
|
+
|
98
|
+
Apipie::Generator::Swagger::Warning.for_code(
|
99
|
+
Apipie::Generator::Swagger::Warning::OPTIONAL_WITHOUT_DEFAULT_VALUE_CODE,
|
100
|
+
method,
|
101
|
+
{ parameter: @param_description.name }
|
102
|
+
).warn_through_writer
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
class Apipie::Generator::Swagger::ParamDescription::Composite
|
2
|
+
# @param [Array<Apipie::ParamDescription>] param_descriptions
|
3
|
+
# @param [Apipie::Generator::Swagger::Context] context
|
4
|
+
def initialize(param_descriptions, context)
|
5
|
+
@param_descriptions = param_descriptions
|
6
|
+
@context = context
|
7
|
+
@schema = {
|
8
|
+
type: 'object',
|
9
|
+
properties: {}
|
10
|
+
}
|
11
|
+
@required_params = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_swagger
|
15
|
+
return if @param_descriptions.blank?
|
16
|
+
|
17
|
+
@param_descriptions.each do |param_description|
|
18
|
+
validate(param_description)
|
19
|
+
|
20
|
+
if param_description.required
|
21
|
+
@required_params.push(param_description.name.to_sym)
|
22
|
+
end
|
23
|
+
|
24
|
+
param_type = Apipie::Generator::Swagger::TypeExtractor.
|
25
|
+
new(param_description.validator).
|
26
|
+
extract
|
27
|
+
|
28
|
+
has_nested_params = param_type == 'object' &&
|
29
|
+
param_description.validator.params_ordered.present?
|
30
|
+
|
31
|
+
if has_nested_params
|
32
|
+
schema = Apipie::Generator::Swagger::ParamDescription::Composite.new(
|
33
|
+
param_description.validator.params_ordered,
|
34
|
+
Apipie::Generator::Swagger::Context.new(
|
35
|
+
allow_null: @context.allow_null?,
|
36
|
+
http_method: @context.http_method,
|
37
|
+
controller_method: @context.controller_method
|
38
|
+
)
|
39
|
+
).to_swagger
|
40
|
+
|
41
|
+
return if schema.blank?
|
42
|
+
|
43
|
+
if param_description.additional_properties
|
44
|
+
schema[:additionalProperties] = true
|
45
|
+
end
|
46
|
+
|
47
|
+
if param_description.is_array?
|
48
|
+
schema = for_array(schema)
|
49
|
+
end
|
50
|
+
|
51
|
+
if @context.allow_null?
|
52
|
+
schema = with_null(schema)
|
53
|
+
end
|
54
|
+
|
55
|
+
if schema.present?
|
56
|
+
@schema[:properties][param_description.name.to_sym] = schema
|
57
|
+
end
|
58
|
+
else
|
59
|
+
param_entry = Apipie::Generator::Swagger::ParamDescription::Builder.
|
60
|
+
new(
|
61
|
+
param_description,
|
62
|
+
in_schema: @context.in_schema?,
|
63
|
+
controller_method: @context.controller_method
|
64
|
+
).
|
65
|
+
with_description(language: @context.language).
|
66
|
+
with_type(with_null: @context.allow_null?).
|
67
|
+
with_in(
|
68
|
+
default_in_value: @context.default_in_value,
|
69
|
+
http_method: @context.http_method
|
70
|
+
).
|
71
|
+
to_swagger
|
72
|
+
|
73
|
+
@schema[:properties][param_description.name.to_sym] = param_entry
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
if !Apipie.configuration.swagger_allow_additional_properties_in_response
|
78
|
+
@schema[:additionalProperties] = false
|
79
|
+
end
|
80
|
+
|
81
|
+
if @required_params.length > 0
|
82
|
+
@schema[:required] = @required_params
|
83
|
+
end
|
84
|
+
|
85
|
+
@schema
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def for_array(schema)
|
91
|
+
{
|
92
|
+
type: 'array',
|
93
|
+
items: schema
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def with_null(schema)
|
98
|
+
# Ideally we would write schema[:type] = ["object", "null"]
|
99
|
+
# but due to a bug in the json-schema gem, we need to use anyOf
|
100
|
+
# see https://github.com/ruby-json-schema/json-schema/issues/404
|
101
|
+
{
|
102
|
+
anyOf: [ schema, { type: 'null' } ]
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
def validate(param_description)
|
107
|
+
if !param_description.respond_to?(:required)
|
108
|
+
raise "Unexpected param_desc format"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Apipie::Generator::Swagger::ParamDescription::Description
|
2
|
+
def initialize(param_description, language:)
|
3
|
+
@param_description = param_description
|
4
|
+
@language = language
|
5
|
+
end
|
6
|
+
|
7
|
+
# @return [Hash]
|
8
|
+
def to_hash
|
9
|
+
description = @param_description.options[:desc]
|
10
|
+
|
11
|
+
return {} if description.blank?
|
12
|
+
|
13
|
+
{ description: Apipie.app.translate(description, @language) }
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Apipie::Generator::Swagger::ParamDescription::In
|
2
|
+
IN_KEYWORD_DEFAULT_VALUES = {
|
3
|
+
form_data: 'formData',
|
4
|
+
query: 'query'
|
5
|
+
}
|
6
|
+
|
7
|
+
def initialize(param_description, in_schema:, default_in_value:, http_method:)
|
8
|
+
@param_description = param_description
|
9
|
+
@in_schema = in_schema
|
10
|
+
@default_in_value = default_in_value
|
11
|
+
@http_method = http_method
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Hash]
|
15
|
+
def to_hash
|
16
|
+
# The "name" and "in" keys can only be set on root parameters (non-nested)
|
17
|
+
return {} if @in_schema
|
18
|
+
|
19
|
+
{ in: in_value }
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def in_value
|
25
|
+
return @default_in_value if @default_in_value.present?
|
26
|
+
|
27
|
+
if body_allowed_for_current_method?
|
28
|
+
IN_KEYWORD_DEFAULT_VALUES[:form_data]
|
29
|
+
else
|
30
|
+
IN_KEYWORD_DEFAULT_VALUES[:query]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def body_allowed_for_current_method?
|
35
|
+
['get', 'head'].exclude?(@http_method)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Apipie::Generator::Swagger::ParamDescription::Name
|
2
|
+
def initialize(param_description, prefixed_by: nil)
|
3
|
+
@param_description = param_description
|
4
|
+
@prefixed_by = prefixed_by
|
5
|
+
end
|
6
|
+
|
7
|
+
# @return [Hash]
|
8
|
+
def to_hash
|
9
|
+
name =
|
10
|
+
if @prefixed_by.present?
|
11
|
+
"#{@prefixed_by}[#{@param_description.name}]"
|
12
|
+
else
|
13
|
+
@param_description.name
|
14
|
+
end
|
15
|
+
|
16
|
+
{ name: name }
|
17
|
+
end
|
18
|
+
end
|