apipie-rails 0.9.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -14
  3. data/.rubocop_todo.yml +102 -213
  4. data/CHANGELOG.md +17 -6
  5. data/README.rst +12 -12
  6. data/app/controllers/apipie/apipies_controller.rb +4 -4
  7. data/lib/apipie/apipie_module.rb +4 -4
  8. data/lib/apipie/application.rb +70 -54
  9. data/lib/apipie/configuration.rb +19 -26
  10. data/lib/apipie/dsl_definition.rb +4 -5
  11. data/lib/apipie/extractor/collector.rb +2 -2
  12. data/lib/apipie/extractor.rb +1 -1
  13. data/lib/apipie/generator/config.rb +12 -0
  14. data/lib/apipie/generator/swagger/computed_interface_id.rb +23 -0
  15. data/lib/apipie/generator/swagger/config.rb +78 -0
  16. data/lib/apipie/generator/swagger/context.rb +12 -1
  17. data/lib/apipie/generator/swagger/method_description/api_decorator.rb +20 -0
  18. data/lib/apipie/generator/swagger/method_description/api_schema_service.rb +86 -0
  19. data/lib/apipie/generator/swagger/method_description/decorator.rb +22 -0
  20. data/lib/apipie/generator/swagger/method_description/parameters_service.rb +139 -0
  21. data/lib/apipie/generator/swagger/method_description/response_schema_service.rb +46 -0
  22. data/lib/apipie/generator/swagger/method_description/response_service.rb +58 -0
  23. data/lib/apipie/generator/swagger/method_description.rb +2 -0
  24. data/lib/apipie/generator/swagger/operation_id.rb +1 -1
  25. data/lib/apipie/generator/swagger/param_description/builder.rb +4 -4
  26. data/lib/apipie/generator/swagger/param_description/composite.rb +9 -1
  27. data/lib/apipie/generator/swagger/param_description/in.rb +1 -1
  28. data/lib/apipie/generator/swagger/param_description/path_params_composite.rb +61 -0
  29. data/lib/apipie/generator/swagger/param_description/referenced_composite.rb +36 -0
  30. data/lib/apipie/generator/swagger/param_description/type.rb +9 -2
  31. data/lib/apipie/generator/swagger/path_decorator.rb +36 -0
  32. data/lib/apipie/generator/swagger/referenced_definitions.rb +17 -0
  33. data/lib/apipie/generator/swagger/resource_description_collection.rb +30 -0
  34. data/lib/apipie/generator/swagger/resource_description_composite.rb +56 -0
  35. data/lib/apipie/generator/swagger/schema.rb +63 -0
  36. data/lib/apipie/generator/swagger/type_extractor.rb +0 -19
  37. data/lib/apipie/generator/swagger/warning.rb +3 -6
  38. data/lib/apipie/generator/swagger/warning_writer.rb +7 -1
  39. data/lib/apipie/method_description.rb +4 -2
  40. data/lib/apipie/param_description.rb +4 -2
  41. data/lib/apipie/resource_description.rb +1 -1
  42. data/lib/apipie/swagger_generator.rb +27 -551
  43. data/lib/apipie/validator.rb +7 -3
  44. data/lib/apipie/version.rb +1 -1
  45. data/lib/apipie-rails.rb +17 -0
  46. data/lib/tasks/apipie.rake +15 -10
  47. data/spec/controllers/api/v2/nested/resources_controller_spec.rb +2 -2
  48. data/spec/controllers/pets_controller_spec.rb +10 -16
  49. data/spec/controllers/users_controller_spec.rb +2 -2
  50. data/spec/dummy/app/controllers/pets_controller.rb +4 -4
  51. data/spec/dummy/app/controllers/pets_using_self_describing_classes_controller.rb +2 -2
  52. data/spec/dummy/app/controllers/twitter_example_controller.rb +2 -2
  53. data/spec/dummy/app/controllers/users_controller.rb +5 -5
  54. data/spec/lib/apipie/application_spec.rb +16 -7
  55. data/spec/lib/apipie/configuration_spec.rb +15 -0
  56. data/spec/lib/apipie/generator/swagger/config_spec.rb +19 -0
  57. data/spec/lib/apipie/generator/swagger/context_spec.rb +22 -2
  58. data/spec/lib/apipie/generator/swagger/method_description/api_schema_service_spec.rb +106 -0
  59. data/spec/lib/apipie/generator/swagger/method_description/response_schema_service_spec.rb +105 -0
  60. data/spec/lib/apipie/generator/swagger/param_description/builder_spec.rb +1 -1
  61. data/spec/lib/apipie/generator/swagger/param_description/composite_spec.rb +2 -2
  62. data/spec/lib/apipie/generator/swagger/param_description/type_spec.rb +7 -7
  63. data/spec/lib/apipie/generator/swagger/path_decorator_spec.rb +57 -0
  64. data/spec/lib/apipie/generator/swagger/referenced_definitions_spec.rb +35 -0
  65. data/spec/lib/apipie/generator/swagger/resource_description_composite_spec.rb +37 -0
  66. data/spec/lib/apipie/generator/swagger/resource_descriptions_collection_spec.rb +57 -0
  67. data/spec/lib/apipie/generator/swagger/schema_spec.rb +89 -0
  68. data/spec/lib/apipie/generator/swagger/type_extractor_spec.rb +0 -43
  69. data/spec/lib/apipie/generator/swagger/warning_spec.rb +1 -1
  70. data/spec/lib/apipie/generator/swagger/warning_writer_spec.rb +19 -7
  71. data/spec/lib/apipie/method_description_spec.rb +101 -66
  72. data/spec/lib/apipie/param_description_spec.rb +209 -49
  73. data/spec/lib/apipie/param_group_spec.rb +1 -0
  74. data/spec/lib/apipie/resource_description_spec.rb +1 -1
  75. data/spec/lib/apipie/swagger_generator_spec.rb +94 -0
  76. data/spec/lib/apipie/validator_spec.rb +47 -11
  77. data/spec/lib/swagger/rake_swagger_spec.rb +4 -4
  78. data/spec/lib/swagger/swagger_dsl_spec.rb +7 -7
  79. data/spec/lib/validators/array_validator_spec.rb +1 -1
  80. metadata +28 -2
@@ -0,0 +1,78 @@
1
+ require 'singleton'
2
+
3
+ module Apipie
4
+ module Generator
5
+ module Swagger
6
+ class Config
7
+ include Singleton
8
+
9
+ CONFIG_ATTRIBUTES = [:include_warning_tags, :content_type_input,
10
+ :json_input_uses_refs, :suppress_warnings, :api_host,
11
+ :generate_x_computed_id_field, :allow_additional_properties_in_response,
12
+ :responses_use_refs, :schemes, :security_definitions,
13
+ :global_security].freeze
14
+
15
+ attr_accessor(*CONFIG_ATTRIBUTES)
16
+
17
+ CONFIG_ATTRIBUTES.each do |attribute|
18
+ old_setter_method = "swagger_#{attribute}="
19
+ define_method(old_setter_method) do |value|
20
+ ActiveSupport::Deprecation.warn(
21
+ <<~HEREDOC
22
+ config.#{old_setter_method}#{value} is deprecated.
23
+ config.generator.swagger.#{attribute} instead.
24
+ HEREDOC
25
+ )
26
+
27
+ send("#{attribute}=", value)
28
+ end
29
+
30
+ old_setter_method = "swagger_#{attribute}"
31
+ define_method(old_setter_method) do
32
+ ActiveSupport::Deprecation.warn(
33
+ <<~HEREDOC
34
+ config.#{old_setter_method} is deprecated.
35
+ Use config.generator.swagger.#{attribute} instead.
36
+ HEREDOC
37
+ )
38
+
39
+ send(attribute)
40
+ end
41
+ end
42
+
43
+ alias include_warning_tags? include_warning_tags
44
+ alias json_input_uses_refs? json_input_uses_refs
45
+ alias responses_use_refs? responses_use_refs
46
+ alias generate_x_computed_id_field? generate_x_computed_id_field
47
+ alias swagger_include_warning_tags? swagger_include_warning_tags
48
+ alias swagger_json_input_uses_refs? swagger_json_input_uses_refs
49
+ alias swagger_responses_use_refs? swagger_responses_use_refs
50
+ alias swagger_generate_x_computed_id_field? swagger_generate_x_computed_id_field
51
+
52
+ def initialize
53
+ @content_type_input = :form_data # this can be :json or :form_data
54
+ @json_input_uses_refs = false
55
+ @include_warning_tags = false
56
+ @suppress_warnings = false # [105,100,102]
57
+ @api_host = 'localhost:3000'
58
+ @generate_x_computed_id_field = false
59
+ @allow_additional_properties_in_response = false
60
+ @responses_use_refs = true
61
+ @schemes = [:https]
62
+ @security_definitions = {}
63
+ @global_security = []
64
+ end
65
+
66
+ def self.deprecated_methods
67
+ CONFIG_ATTRIBUTES.map do |attribute|
68
+ [
69
+ :"swagger_#{attribute}=",
70
+ :"swagger_#{attribute}?",
71
+ :"swagger_#{attribute}"
72
+ ]
73
+ end.flatten
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,10 +1,12 @@
1
1
  class Apipie::Generator::Swagger::Context
2
- attr_reader :default_in_value, :language, :http_method, :controller_method
2
+ attr_reader :default_in_value, :language, :http_method, :controller_method,
3
+ :prefix
3
4
 
4
5
  def initialize(
5
6
  allow_null:,
6
7
  http_method:,
7
8
  controller_method:,
9
+ prefix: nil,
8
10
  default_in_value: nil,
9
11
  language: nil,
10
12
  in_schema: true
@@ -15,6 +17,7 @@ class Apipie::Generator::Swagger::Context
15
17
  @in_schema = in_schema
16
18
  @http_method = http_method
17
19
  @controller_method = controller_method
20
+ @prefix = prefix
18
21
  end
19
22
 
20
23
  def allow_null?
@@ -24,4 +27,12 @@ class Apipie::Generator::Swagger::Context
24
27
  def in_schema?
25
28
  @in_schema == true
26
29
  end
30
+
31
+ def add_to_prefix!(prefix)
32
+ @prefix = if @prefix.present?
33
+ "#{@prefix}[#{prefix}]"
34
+ else
35
+ prefix
36
+ end
37
+ end
27
38
  end
@@ -0,0 +1,20 @@
1
+ class Apipie::Generator::Swagger::MethodDescription::ApiDecorator < SimpleDelegator
2
+ def normalized_http_method
3
+ @normalized_http_method ||= http_method.downcase
4
+ end
5
+
6
+ def summary(method_description:, language:)
7
+ s = Apipie.app.translate(short_description, language)
8
+
9
+ if s.blank?
10
+ Apipie::Generator::Swagger::Warning.for_code(
11
+ Apipie::Generator::Swagger::Warning::MISSING_METHOD_SUMMARY_CODE,
12
+ method_description.ruby_name
13
+ ).warn_through_writer
14
+
15
+ nil
16
+ else
17
+ s
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,86 @@
1
+ class Apipie::Generator::Swagger::MethodDescription::ApiSchemaService
2
+ # @param [Apipie::Generator::Swagger::MethodDescription::Decorator] method_description
3
+ def initialize(method_description, language: nil)
4
+ @method_description = method_description
5
+ @language = language
6
+ end
7
+
8
+ # @return [Hash]
9
+ def call
10
+ @method_description.apis.each_with_object({}) do |api, paths|
11
+ api = Apipie::Generator::Swagger::MethodDescription::ApiDecorator.new(api)
12
+ path = Apipie::Generator::Swagger::PathDecorator.new(api.path)
13
+ op_id = Apipie::Generator::Swagger::OperationId.from(api).to_s
14
+
15
+ if Apipie.configuration.generator.swagger.generate_x_computed_id_field?
16
+ Apipie::Generator::Swagger::ComputedInterfaceId.instance.add!(op_id)
17
+ end
18
+
19
+ parameters = Apipie::Generator::Swagger::MethodDescription::ParametersService
20
+ .new(@method_description, path: path, http_method: api.normalized_http_method)
21
+ .call
22
+
23
+ paths[path.swagger_path(@method_description)] ||= {}
24
+ paths[path.swagger_path(@method_description)][api.normalized_http_method] = {
25
+ tags: tags,
26
+ consumes: consumes,
27
+ operationId: op_id,
28
+ summary: api.summary(method_description: @method_description, language: @language),
29
+ parameters: parameters,
30
+ responses: responses(api),
31
+ description: Apipie.app.translate(@method_description.full_description, @language)
32
+ }.compact
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def summary(api)
39
+ translated_description = Apipie.app.translate(api.short_description, @language)
40
+
41
+ return translated_description if translated_description.present?
42
+
43
+ Apipie::Generator::Swagger::Warning.for_code(
44
+ Apipie::Generator::Swagger::Warning::MISSING_METHOD_SUMMARY_CODE,
45
+ @method_description.ruby_name
46
+ ).warn_through_writer
47
+ end
48
+
49
+ def tags
50
+ [@method_description.resource._id] +
51
+ warning_tags +
52
+ @method_description.tag_list.tags
53
+ end
54
+
55
+ def warning_tags
56
+ if Apipie.configuration.generator.swagger.include_warning_tags? &&
57
+ Apipie::Generator::Swagger::WarningWriter.instance.issued_warnings?
58
+ ['warnings issued']
59
+ else
60
+ []
61
+ end
62
+ end
63
+
64
+ def consumes
65
+ if params_in_body?
66
+ ['application/json']
67
+ else
68
+ ['application/x-www-form-urlencoded', 'multipart/form-data']
69
+ end
70
+ end
71
+
72
+ def params_in_body?
73
+ Apipie.configuration.generator.swagger.content_type_input == :json
74
+ end
75
+
76
+ # @param [Apipie::Generator::Swagger::MethodDescription::ApiDecorator] api
77
+ def responses(api)
78
+ Apipie::Generator::Swagger::MethodDescription::ResponseService
79
+ .new(
80
+ @method_description,
81
+ language: @language,
82
+ http_method: api.normalized_http_method
83
+ )
84
+ .call
85
+ end
86
+ end
@@ -0,0 +1,22 @@
1
+ class Apipie::Generator::Swagger::MethodDescription::Decorator < SimpleDelegator
2
+ # @return [String]
3
+ def operation_id
4
+ "#{object.resource.controller.name}__#{object.method_name}"
5
+ end
6
+
7
+ # @return [String]
8
+ def ruby_name
9
+ if object.blank?
10
+ '<no method>'
11
+ else
12
+ "#{object.resource.controller.name}##{object.method_name}"
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ # @return [Apipie::MethodDescription, nil]
19
+ def object
20
+ __getobj__
21
+ end
22
+ end
@@ -0,0 +1,139 @@
1
+ class Apipie::Generator::Swagger::MethodDescription::ParametersService
2
+ # @param [Apipie::Generator::Swagger::MethodDescription::Decorator] method_description
3
+ # @param [Apipie::Generator::Swagger::PathDecorator] path
4
+ # @param [Symbol] http_method
5
+ def initialize(method_description, path:, http_method:)
6
+ @method_description = method_description
7
+ @path = path
8
+ @http_method = http_method
9
+ end
10
+
11
+ # @return [Array]
12
+ def call
13
+ path_params_schema + body_params_schema + header_params_schema
14
+ end
15
+
16
+ private
17
+
18
+ def path_params_schema
19
+ Apipie::Generator::Swagger::ParamDescription::PathParamsComposite.new(
20
+ path_param_descriptions,
21
+ Apipie::Generator::Swagger::Context.new(
22
+ allow_null: false,
23
+ default_in_value: 'path',
24
+ http_method: @http_method,
25
+ controller_method: @method_description
26
+ )
27
+ ).to_swagger
28
+ end
29
+
30
+ def body_params_schema
31
+ if params_in_body? && body_allowed_for_current_method?
32
+ composite = Apipie::Generator::Swagger::ParamDescription::Composite.new(
33
+ body_param_descriptions,
34
+ Apipie::Generator::Swagger::Context.new(
35
+ allow_null: false,
36
+ http_method: @http_method,
37
+ controller_method: @method_description
38
+ )
39
+ )
40
+
41
+ if Apipie.configuration.generator.swagger.json_input_uses_refs?
42
+ composite = composite
43
+ .referenced("#{@method_description.operation_id}_input")
44
+ end
45
+
46
+ swagger_schema_for_body = composite.to_swagger
47
+
48
+ swagger_body_param = {
49
+ name: 'body',
50
+ in: 'body',
51
+ schema: swagger_schema_for_body
52
+ }
53
+
54
+ if swagger_schema_for_body.present?
55
+ [swagger_body_param]
56
+ else
57
+ []
58
+ end
59
+ else
60
+ Apipie::Generator::Swagger::ParamDescription::PathParamsComposite.new(
61
+ body_param_descriptions,
62
+ Apipie::Generator::Swagger::Context.new(
63
+ allow_null: false,
64
+ http_method: @http_method,
65
+ controller_method: @method_description
66
+ )
67
+ ).to_swagger
68
+ end
69
+ end
70
+
71
+ def all_params
72
+ @all_params ||=
73
+ begin
74
+ param_names_from_method = @method_description.params.keys
75
+ missing = @path.param_names - param_names_from_method
76
+
77
+ result = @method_description.params
78
+
79
+ missing.each do |name|
80
+ warn_path_parameter_not_described(name, @path)
81
+
82
+ result[name.to_sym] = Apipie::Generator::Swagger::ParamDescription
83
+ .create_for_missing_param(@method_description, name)
84
+ end
85
+
86
+ result
87
+ end
88
+ end
89
+
90
+ def body_param_descriptions
91
+ @body_param_descriptions ||= all_params
92
+ .reject { |k, _| @path.param?(k) }
93
+ .values
94
+ end
95
+
96
+ def path_param_descriptions
97
+ @path_param_descriptions ||= all_params
98
+ .select { |k, _| @path.param?(k) }
99
+ .each { |_, desc| desc.required = true }
100
+ .values
101
+ end
102
+
103
+ # @return [Array]
104
+ def header_params_schema
105
+ return [] if @method_description.headers.blank?
106
+
107
+ @method_description.headers.map do |header|
108
+ header_hash = {
109
+ name: header[:name],
110
+ in: 'header',
111
+ required: header[:options][:required],
112
+ description: header[:description],
113
+ type: header[:options][:type] || 'string'
114
+
115
+ }
116
+ if header[:options][:default]
117
+ header_hash[:default] = header[:options][:default]
118
+ end
119
+
120
+ header_hash
121
+ end
122
+ end
123
+
124
+ def params_in_body?
125
+ Apipie.configuration.generator.swagger.content_type_input == :json
126
+ end
127
+
128
+ def body_allowed_for_current_method?
129
+ %w[get head].exclude?(@http_method)
130
+ end
131
+
132
+ def warn_path_parameter_not_described(name, path)
133
+ Apipie::Generator::Swagger::Warning.for_code(
134
+ Apipie::Generator::Swagger::Warning::PATH_PARAM_NOT_DESCRIBED_CODE,
135
+ @method_description.ruby_name,
136
+ { name: name, path: path }
137
+ ).warn_through_writer
138
+ end
139
+ end
@@ -0,0 +1,46 @@
1
+ class Apipie::Generator::Swagger::MethodDescription::ResponseSchemaService
2
+ # @param [Apipie::ResponseDescription, Apipie::ResponseDescriptionAdapter] response_description
3
+ def initialize(response_description, allow_null:, http_method:, controller_method:)
4
+ @response_description = response_description
5
+ @allow_null = allow_null
6
+ @http_method = http_method
7
+ @controller_method = controller_method
8
+ end
9
+
10
+ def to_swagger
11
+ composite = Apipie::Generator::Swagger::ParamDescription::Composite.new(
12
+ @response_description.params_ordered,
13
+ Apipie::Generator::Swagger::Context.new(
14
+ allow_null: @allow_null,
15
+ http_method: @http_method,
16
+ controller_method: @controller_method
17
+ )
18
+ )
19
+
20
+ if Apipie.configuration.generator.swagger.responses_use_refs? && @response_description.typename.present?
21
+ composite = composite.referenced(@response_description.typename)
22
+ end
23
+
24
+ schema = composite.to_swagger
25
+
26
+ if @response_description.is_array? && schema
27
+ schema = { type: type_for_array, items: schema }
28
+ end
29
+
30
+ if @response_description.allow_additional_properties
31
+ schema[:additionalProperties] = true
32
+ end
33
+
34
+ schema
35
+ end
36
+
37
+ private
38
+
39
+ def type_for_array
40
+ if @allow_null == true
41
+ %w[array null]
42
+ else
43
+ 'array'
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,58 @@
1
+ class Apipie::Generator::Swagger::MethodDescription::ResponseService
2
+ # @param [Apipie::Generator::Swagger::MethodDescription::Decorator] method_description
3
+ # @param [Symbol] http_method
4
+ def initialize(method_description, http_method:, language:)
5
+ @method_description = method_description
6
+ @http_method = http_method
7
+ @language = language
8
+ end
9
+
10
+ # @return [Hash]
11
+ def call
12
+ result = {}
13
+ result.merge!(errors)
14
+ result.merge!(responses)
15
+ result.merge!(empty_returns)
16
+
17
+ result
18
+ end
19
+
20
+ private
21
+
22
+ # @return [Hash]
23
+ def errors
24
+ @errors ||= @method_description.errors.each_with_object({}) do |error, errors|
25
+ errors[error.code] = {
26
+ description: Apipie.app.translate(error.description, @language)
27
+ }
28
+ end
29
+ end
30
+
31
+ # @return [Hash]
32
+ def responses
33
+ @responses ||=
34
+ @method_description.returns.each_with_object({}) do |response, responses_schema|
35
+ responses_schema[response.code] = {
36
+ description: Apipie.app.translate(response.description, @language),
37
+ schema: Apipie::Generator::Swagger::MethodDescription::ResponseSchemaService.new(
38
+ response,
39
+ allow_null: false,
40
+ http_method: @http_method,
41
+ controller_method: @method_description
42
+ ).to_swagger
43
+ }.compact
44
+ end
45
+ end
46
+
47
+ # @return [Hash]
48
+ def empty_returns
49
+ return {} if errors.present? || responses.present?
50
+
51
+ Apipie::Generator::Swagger::Warning.for_code(
52
+ Apipie::Generator::Swagger::Warning::NO_RETURN_CODES_SPECIFIED_CODE,
53
+ @method_description.ruby_name
54
+ ).warn_through_writer
55
+
56
+ { 200 => { description: 'ok' } }
57
+ end
58
+ end
@@ -0,0 +1,2 @@
1
+ module Apipie::Generator::Swagger::MethodDescription
2
+ end
@@ -22,7 +22,7 @@ class Apipie::Generator::Swagger::OperationId
22
22
  # @return [Apipie::Generator::Swagger::OperationId]
23
23
  def self.from(describable, param: nil)
24
24
  path, http_method =
25
- if describable.is_a?(Apipie::MethodDescription::Api)
25
+ if describable.respond_to?(:path) && describable.respond_to?(:http_method)
26
26
  [describable.path, describable.http_method]
27
27
  elsif describable.is_a?(Apipie::MethodDescription)
28
28
  [describable.apis.first.path, describable.apis.first.http_method]
@@ -1,7 +1,7 @@
1
1
  class Apipie::Generator::Swagger::ParamDescription::Builder
2
2
  # @param [Apipie::ParamDescription] param_description
3
3
  # @param [TrueClass, FalseClass] in_schema
4
- # @param [String] controller_method
4
+ # @param [Apipie::MethodDescription] controller_method
5
5
  def initialize(param_description, in_schema:, controller_method:)
6
6
  @param_description = param_description
7
7
  @in_schema = in_schema
@@ -88,16 +88,16 @@ class Apipie::Generator::Swagger::ParamDescription::Builder
88
88
 
89
89
  def warn_optional_without_default_value(definition)
90
90
  if !required? && !definition.key?(:default)
91
- method =
91
+ method_id =
92
92
  if @param_description.is_a?(Apipie::ResponseDescriptionAdapter::PropDesc)
93
93
  @controller_method
94
94
  else
95
- @param_description.method_description.method
95
+ Apipie::Generator::Swagger::MethodDescription::Decorator.new(@controller_method).ruby_name
96
96
  end
97
97
 
98
98
  Apipie::Generator::Swagger::Warning.for_code(
99
99
  Apipie::Generator::Swagger::Warning::OPTIONAL_WITHOUT_DEFAULT_VALUE_CODE,
100
- method,
100
+ method_id,
101
101
  { parameter: @param_description.name }
102
102
  ).warn_through_writer
103
103
  end
@@ -74,7 +74,7 @@ class Apipie::Generator::Swagger::ParamDescription::Composite
74
74
  end
75
75
  end
76
76
 
77
- if !Apipie.configuration.swagger_allow_additional_properties_in_response
77
+ if !Apipie.configuration.generator.swagger.allow_additional_properties_in_response
78
78
  @schema[:additionalProperties] = false
79
79
  end
80
80
 
@@ -85,6 +85,14 @@ class Apipie::Generator::Swagger::ParamDescription::Composite
85
85
  @schema
86
86
  end
87
87
 
88
+ # @param [Symbol, String] param_type
89
+ #
90
+ # @return [Apipie::Generator::Swagger::ParamDescription::ReferencedComposite]
91
+ def referenced(param_type)
92
+ Apipie::Generator::Swagger::ParamDescription::ReferencedComposite.
93
+ new(self, param_type)
94
+ end
95
+
88
96
  private
89
97
 
90
98
  def for_array(schema)
@@ -32,6 +32,6 @@ class Apipie::Generator::Swagger::ParamDescription::In
32
32
  end
33
33
 
34
34
  def body_allowed_for_current_method?
35
- ['get', 'head'].exclude?(@http_method)
35
+ %w[get head].exclude?(@http_method)
36
36
  end
37
37
  end
@@ -0,0 +1,61 @@
1
+ class Apipie::Generator::Swagger::ParamDescription::PathParamsComposite
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
+ @result = []
8
+ end
9
+
10
+ # @return [Array]
11
+ def to_swagger
12
+ @param_descriptions.each do |desc|
13
+ context = @context.dup
14
+
15
+ type = Apipie::Generator::Swagger::TypeExtractor.new(desc.validator).extract
16
+
17
+ if type == 'object' && desc.validator.params_ordered.blank?
18
+ warn_param_ignored_in_form_data(desc.name)
19
+ next
20
+ end
21
+
22
+ has_nested_params = type == 'object' &&
23
+ desc.validator.params_ordered.present?
24
+
25
+ if has_nested_params
26
+ context.add_to_prefix!(desc.name)
27
+
28
+ out = Apipie::Generator::Swagger::ParamDescription::PathParamsComposite
29
+ .new(desc.validator.params_ordered, context)
30
+ .to_swagger
31
+
32
+ @result.concat(out)
33
+ else
34
+ param_entry =
35
+ Apipie::Generator::Swagger::ParamDescription::Builder
36
+ .new(desc, in_schema: false, controller_method: context.controller_method)
37
+ .with_description(language: context.language)
38
+ .with_name(prefix: context.prefix)
39
+ .with_type(with_null: context.allow_null?)
40
+ .with_in(
41
+ http_method: context.http_method,
42
+ default_in_value: context.default_in_value
43
+ ).to_swagger
44
+
45
+ @result << param_entry
46
+ end
47
+ end
48
+
49
+ @result.sort_by { |p| p[:required] ? 0 : 1 }
50
+ end
51
+
52
+ private
53
+
54
+ def warn_param_ignored_in_form_data(name)
55
+ Apipie::Generator::Swagger::Warning.for_code(
56
+ Apipie::Generator::Swagger::Warning::PARAM_IGNORED_IN_FORM_DATA_CODE,
57
+ @context.controller_method.ruby_name,
58
+ { parameter: name }
59
+ ).warn_through_writer
60
+ end
61
+ end
@@ -0,0 +1,36 @@
1
+ # A Composite that keeps track when a param description has been added to references
2
+ # and returns the reference instead of the complete object
3
+ class Apipie::Generator::Swagger::ParamDescription::ReferencedComposite
4
+ # @param [Apipie::Generator::Swagger::ParamDescription::Composite] composite
5
+ # @param [Symbol, String] param_type
6
+ def initialize(composite, param_type)
7
+ @composite = composite
8
+ @param_type = param_type.to_sym
9
+ end
10
+
11
+ def to_swagger
12
+ return ref_to(:name) if added?(:name)
13
+
14
+ schema_obj = @composite.to_swagger
15
+
16
+ return nil if schema_obj.nil?
17
+
18
+ add(schema_obj)
19
+
20
+ { '$ref' => ref_to(@param_type) }
21
+ end
22
+
23
+ private
24
+
25
+ def ref_to(name)
26
+ "#/definitions/#{name}"
27
+ end
28
+
29
+ def add(schema)
30
+ Apipie::Generator::Swagger::ReferencedDefinitions.instance.add!(@param_type, schema)
31
+ end
32
+
33
+ def added?(name)
34
+ Apipie::Generator::Swagger::ReferencedDefinitions.instance.added?(name)
35
+ end
36
+ end
@@ -44,7 +44,7 @@ class Apipie::Generator::Swagger::ParamDescription::Type
44
44
  private
45
45
 
46
46
  def params_in_body_use_reference?
47
- Apipie.configuration.swagger_json_input_uses_refs
47
+ Apipie.configuration.generator.swagger.json_input_uses_refs
48
48
  end
49
49
 
50
50
  # @return [Apipie::Generator::Swagger::Type, String]
@@ -99,9 +99,16 @@ class Apipie::Generator::Swagger::ParamDescription::Type
99
99
  end
100
100
 
101
101
  def warn_hash_without_internal_typespec
102
+ method_id =
103
+ if @param_description.is_a?(Apipie::ResponseDescriptionAdapter::PropDesc)
104
+ @controller_method.method
105
+ else
106
+ Apipie::Generator::Swagger::MethodDescription::Decorator.new(@param_description.method_description).ruby_name
107
+ end
108
+
102
109
  Apipie::Generator::Swagger::Warning.for_code(
103
110
  Apipie::Generator::Swagger::Warning::HASH_WITHOUT_INTERNAL_TYPESPEC_CODE,
104
- @controller_method,
111
+ method_id,
105
112
  { parameter: @param_description.name }
106
113
  ).warn_through_writer
107
114
  end