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
@@ -0,0 +1,108 @@
|
|
1
|
+
class Apipie::Generator::Swagger::ParamDescription::Type
|
2
|
+
def initialize(param_description, with_null:, controller_method:)
|
3
|
+
@param_description = param_description
|
4
|
+
@with_null = with_null
|
5
|
+
@controller_method = controller_method
|
6
|
+
end
|
7
|
+
|
8
|
+
# @return [Hash]
|
9
|
+
def to_hash
|
10
|
+
type_definition = {}
|
11
|
+
|
12
|
+
case type.to_s
|
13
|
+
when 'array'
|
14
|
+
type_definition.merge!(for_array_type)
|
15
|
+
when 'enum'
|
16
|
+
type_definition.merge!(for_enum_type)
|
17
|
+
when 'object'
|
18
|
+
# We only get here if there is no specification
|
19
|
+
# of properties for this object.
|
20
|
+
type_definition.merge!(for_object_type)
|
21
|
+
warn_hash_without_internal_typespec
|
22
|
+
else
|
23
|
+
type_definition.merge!({ type: type.to_s })
|
24
|
+
end
|
25
|
+
|
26
|
+
if @param_description.is_array?
|
27
|
+
type_definition = {
|
28
|
+
items: type_definition,
|
29
|
+
type: 'array'
|
30
|
+
}
|
31
|
+
|
32
|
+
if @with_null
|
33
|
+
type_definition[:type] = [type_definition[:type], 'null']
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
if @with_null
|
38
|
+
type_definition[:type] = [type_definition[:type], 'null']
|
39
|
+
end
|
40
|
+
|
41
|
+
type_definition
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def params_in_body_use_reference?
|
47
|
+
Apipie.configuration.swagger_json_input_uses_refs
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Apipie::Generator::Swagger::Type, String]
|
51
|
+
def type
|
52
|
+
@_type ||= Apipie::Generator::Swagger::TypeExtractor.
|
53
|
+
new(validator).
|
54
|
+
extract
|
55
|
+
end
|
56
|
+
|
57
|
+
def for_array_type
|
58
|
+
validator_opts = validator.param_description.options
|
59
|
+
items_type = validator_opts[:of].to_s || validator_opts[:array_of].to_s
|
60
|
+
|
61
|
+
if items_type == 'Hash' && params_in_body_use_reference?
|
62
|
+
reference_name = Apipie::Generator::Swagger::OperationId.
|
63
|
+
from(@param_description.method_description, param: @param_description.name).
|
64
|
+
to_s
|
65
|
+
|
66
|
+
items = {
|
67
|
+
'$ref' => reference_name
|
68
|
+
}
|
69
|
+
else
|
70
|
+
items = { type: 'string' }
|
71
|
+
end
|
72
|
+
|
73
|
+
enum = @param_description.options[:in]
|
74
|
+
|
75
|
+
items[:enum] = enum if enum.present?
|
76
|
+
|
77
|
+
{
|
78
|
+
type: 'array',
|
79
|
+
items: items
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def for_enum_type
|
84
|
+
{
|
85
|
+
type: 'string',
|
86
|
+
enum: @param_description.validator.values
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
def for_object_type
|
91
|
+
{
|
92
|
+
type: 'object',
|
93
|
+
additionalProperties: true
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def validator
|
98
|
+
@_validator ||= @param_description.validator
|
99
|
+
end
|
100
|
+
|
101
|
+
def warn_hash_without_internal_typespec
|
102
|
+
Apipie::Generator::Swagger::Warning.for_code(
|
103
|
+
Apipie::Generator::Swagger::Warning::HASH_WITHOUT_INTERNAL_TYPESPEC_CODE,
|
104
|
+
@controller_method,
|
105
|
+
{ parameter: @param_description.name }
|
106
|
+
).warn_through_writer
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Apipie::Generator::Swagger::ParamDescription
|
2
|
+
# @param [Apipie::MethodDescription] method_description
|
3
|
+
# @param [String] name
|
4
|
+
#
|
5
|
+
# @return [Apipie::ParamDescription]
|
6
|
+
def self.create_for_missing_param(method_description, name)
|
7
|
+
Apipie::ParamDescription.new(
|
8
|
+
method_description,
|
9
|
+
name,
|
10
|
+
Numeric,
|
11
|
+
{
|
12
|
+
in: "path",
|
13
|
+
required: true,
|
14
|
+
added_from_path: true,
|
15
|
+
}
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
@@ -34,8 +34,6 @@ class Apipie::Generator::Swagger::TypeExtractor
|
|
34
34
|
extract
|
35
35
|
end
|
36
36
|
|
37
|
-
private
|
38
|
-
|
39
37
|
def extract
|
40
38
|
expected_type =
|
41
39
|
if string?
|
@@ -51,6 +49,8 @@ class Apipie::Generator::Swagger::TypeExtractor
|
|
51
49
|
TYPES[expected_type] || @validator.expected_type
|
52
50
|
end
|
53
51
|
|
52
|
+
private
|
53
|
+
|
54
54
|
def string?
|
55
55
|
@validator.blank?
|
56
56
|
end
|
@@ -10,8 +10,7 @@ module Apipie
|
|
10
10
|
@from_concern = dsl_data[:from_concern]
|
11
11
|
@apis = ApisService.new(resource, method, dsl_data).call
|
12
12
|
|
13
|
-
|
14
|
-
@full_description = Apipie.markup_to_html(desc)
|
13
|
+
@full_description = dsl_data[:description] || ''
|
15
14
|
|
16
15
|
@errors = dsl_data[:errors].map do |args|
|
17
16
|
Apipie::ErrorDescription.from_dsl_data(args)
|
@@ -40,7 +39,7 @@ module Apipie
|
|
40
39
|
@params_ordered = ParamDescription.unify(@params_ordered)
|
41
40
|
@headers = dsl_data[:headers]
|
42
41
|
|
43
|
-
@show = if dsl_data.
|
42
|
+
@show = if dsl_data.key? :show
|
44
43
|
dsl_data[:show]
|
45
44
|
else
|
46
45
|
true
|
@@ -166,8 +165,8 @@ module Apipie
|
|
166
165
|
:name => @method,
|
167
166
|
:apis => method_apis_to_json(lang),
|
168
167
|
:formats => formats,
|
169
|
-
:full_description => Apipie.app.translate(@full_description, lang),
|
170
|
-
:errors => errors.map(
|
168
|
+
:full_description => Apipie.markup_to_html(Apipie.app.translate(@full_description, lang)),
|
169
|
+
:errors => errors.map{ |error| error.to_json(lang) }.flatten,
|
171
170
|
:params => params_ordered.map{ |param| param.to_json(lang) }.flatten,
|
172
171
|
:returns => @returns.map{ |return_item| return_item.to_json(lang) }.flatten,
|
173
172
|
:examples => @examples,
|
@@ -12,9 +12,9 @@ module Apipie
|
|
12
12
|
attr_reader :additional_properties, :is_array
|
13
13
|
attr_accessor :parent, :required
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
alias response_only? response_only
|
16
|
+
alias request_only? request_only
|
17
|
+
alias is_array? is_array
|
18
18
|
|
19
19
|
def self.from_dsl_data(method_description, args)
|
20
20
|
param_name, validator, desc_or_options, options, block = args
|
@@ -71,7 +71,7 @@ module Apipie
|
|
71
71
|
@request_only = (@options[:only_in] == :request)
|
72
72
|
raise ArgumentError.new("'#{@options[:only_in]}' is not a valid value for :only_in") if (!@response_only && !@request_only) && @options[:only_in].present?
|
73
73
|
|
74
|
-
@show = if @options.
|
74
|
+
@show = if @options.key? :show
|
75
75
|
@options[:show]
|
76
76
|
else
|
77
77
|
true
|
@@ -212,7 +212,7 @@ module Apipie
|
|
212
212
|
# action awareness is being inherited from ancestors (in terms of
|
213
213
|
# nested params)
|
214
214
|
def action_aware?
|
215
|
-
if @options.
|
215
|
+
if @options.key?(:action_aware)
|
216
216
|
return @options[:action_aware]
|
217
217
|
elsif @parent
|
218
218
|
@parent.action_aware?
|
@@ -237,7 +237,7 @@ module Apipie
|
|
237
237
|
# crate/update actions.
|
238
238
|
def action_awareness
|
239
239
|
if action_aware?
|
240
|
-
if !@options.
|
240
|
+
if !@options.key?(:allow_nil)
|
241
241
|
if @required
|
242
242
|
@allow_nil = false
|
243
243
|
else
|
@@ -268,7 +268,7 @@ module Apipie
|
|
268
268
|
end
|
269
269
|
|
270
270
|
def is_required?
|
271
|
-
if @options.
|
271
|
+
if @options.key?(:required)
|
272
272
|
if (@options[:required] == true) || (@options[:required] == false)
|
273
273
|
@options[:required]
|
274
274
|
else
|
@@ -35,7 +35,7 @@ module Apipie
|
|
35
35
|
|
36
36
|
def update_from_dsl_data(dsl_data)
|
37
37
|
@_name = dsl_data[:resource_name] if dsl_data[:resource_name]
|
38
|
-
@_full_description =
|
38
|
+
@_full_description = dsl_data[:description]
|
39
39
|
@_short_description = dsl_data[:short_description]
|
40
40
|
@_path = dsl_data[:path] || ""
|
41
41
|
@_formats = dsl_data[:formats]
|
@@ -71,7 +71,7 @@ module Apipie
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def remove_method_description(method_name)
|
74
|
-
if @_methods.
|
74
|
+
if @_methods.key?(method_name)
|
75
75
|
@_methods.delete(method_name)
|
76
76
|
end
|
77
77
|
end
|
@@ -110,7 +110,7 @@ module Apipie
|
|
110
110
|
:api_url => api_url,
|
111
111
|
:name => @_name,
|
112
112
|
:short_description => Apipie.app.translate(@_short_description, lang),
|
113
|
-
:full_description => Apipie.app.translate(@_full_description, lang),
|
113
|
+
:full_description => Apipie.markup_to_html(Apipie.app.translate(@_full_description, lang)),
|
114
114
|
:version => _version,
|
115
115
|
:formats => @_formats,
|
116
116
|
:metadata => @_metadata,
|
@@ -116,12 +116,12 @@ module Apipie
|
|
116
116
|
def additional_properties
|
117
117
|
!!@response_object.additional_properties
|
118
118
|
end
|
119
|
-
alias
|
119
|
+
alias allow_additional_properties additional_properties
|
120
120
|
|
121
121
|
def to_json(lang=nil)
|
122
122
|
{
|
123
123
|
:code => code,
|
124
|
-
:description => description,
|
124
|
+
:description => Apipie.app.translate(description, lang),
|
125
125
|
:is_array => is_array?,
|
126
126
|
:returns_object => params_ordered.map{ |param| param.to_json(lang).tap{|h| h.delete(:validations) }}.flatten,
|
127
127
|
:additional_properties => additional_properties,
|
@@ -107,9 +107,10 @@ module Apipie
|
|
107
107
|
|
108
108
|
def add_sub_property(prop_desc)
|
109
109
|
raise "Only properties with expected_type 'object' can have sub-properties" unless @expected_type == 'object'
|
110
|
-
|
110
|
+
case prop_desc
|
111
|
+
when PropDesc
|
111
112
|
@sub_properties << prop_desc
|
112
|
-
|
113
|
+
when Modifier
|
113
114
|
prop_desc.apply(self)
|
114
115
|
else
|
115
116
|
raise "Unrecognized prop_desc type (#{prop_desc.class})"
|
@@ -130,7 +131,7 @@ module Apipie
|
|
130
131
|
attr_reader :name, :required, :expected_type, :options, :description
|
131
132
|
attr_accessor :additional_properties
|
132
133
|
|
133
|
-
|
134
|
+
alias desc description
|
134
135
|
|
135
136
|
def is_array?
|
136
137
|
@is_array
|
@@ -170,9 +171,10 @@ module Apipie
|
|
170
171
|
end
|
171
172
|
|
172
173
|
def add(prop_desc)
|
173
|
-
|
174
|
+
case prop_desc
|
175
|
+
when PropDesc
|
174
176
|
@property_descs << prop_desc
|
175
|
-
|
177
|
+
when Modifier
|
176
178
|
prop_desc.apply(self)
|
177
179
|
else
|
178
180
|
raise "Unrecognized prop_desc type (#{prop_desc.class})"
|
@@ -36,7 +36,6 @@ module Apipie
|
|
36
36
|
def generate_from_resources(version, resources, method_name, lang, clear_warnings=false)
|
37
37
|
init_swagger_vars(version, lang, clear_warnings)
|
38
38
|
|
39
|
-
@lang = lang
|
40
39
|
@only_method = method_name
|
41
40
|
add_resources(resources)
|
42
41
|
|
@@ -143,13 +142,6 @@ module Apipie
|
|
143
142
|
warn(Apipie::Generator::Swagger::Warning::NO_RETURN_CODES_SPECIFIED_CODE)
|
144
143
|
end
|
145
144
|
|
146
|
-
def warn_hash_without_internal_typespec(param_name)
|
147
|
-
warn(
|
148
|
-
Apipie::Generator::Swagger::Warning::HASH_WITHOUT_INTERNAL_TYPESPEC_CODE,
|
149
|
-
{ parameter: param_name }
|
150
|
-
)
|
151
|
-
end
|
152
|
-
|
153
145
|
def warn_optional_param_in_path(param_name)
|
154
146
|
warn(
|
155
147
|
Apipie::Generator::Swagger::Warning::OPTIONAL_PARAM_IN_PATH_CODE,
|
@@ -261,7 +253,7 @@ module Apipie
|
|
261
253
|
warning_tags = []
|
262
254
|
end
|
263
255
|
|
264
|
-
op_id =
|
256
|
+
op_id = Apipie::Generator::Swagger::OperationId.from(api).to_s
|
265
257
|
|
266
258
|
include_op_id_in_computed_interface_id(op_id)
|
267
259
|
|
@@ -275,7 +267,7 @@ module Apipie
|
|
275
267
|
summary: Apipie.app.translate(api.short_description, @current_lang),
|
276
268
|
parameters: swagger_params_array_for_method(ruby_method, api.path),
|
277
269
|
responses: responses,
|
278
|
-
description: ruby_method.full_description
|
270
|
+
description: Apipie.app.translate(ruby_method.full_description, @current_lang)
|
279
271
|
}
|
280
272
|
|
281
273
|
if methods[method_key][:summary].nil?
|
@@ -283,6 +275,7 @@ module Apipie
|
|
283
275
|
warn_missing_method_summary
|
284
276
|
end
|
285
277
|
end
|
278
|
+
|
286
279
|
end
|
287
280
|
|
288
281
|
#--------------------------------------------------------------------------
|
@@ -308,16 +301,6 @@ module Apipie
|
|
308
301
|
remove_colons method.resource.controller.name + "::" + method.method
|
309
302
|
end
|
310
303
|
|
311
|
-
def swagger_id_for_typename(typename)
|
312
|
-
typename
|
313
|
-
end
|
314
|
-
|
315
|
-
def swagger_op_id_for_path(http_method, path)
|
316
|
-
# using lowercase http method, because the 'swagger-codegen' tool outputs
|
317
|
-
# strange method names if the http method is in uppercase
|
318
|
-
http_method.downcase + path.gsub(/\//,'_').gsub(/:(\w+)/, '\1').gsub(/_$/,'')
|
319
|
-
end
|
320
|
-
|
321
304
|
def swagger_param_type(param_desc)
|
322
305
|
if param_desc.blank?
|
323
306
|
raise ArgumentError, 'param_desc is required'
|
@@ -343,11 +326,10 @@ module Apipie
|
|
343
326
|
def json_schema_for_method_response(method, return_code, allow_nulls)
|
344
327
|
@definitions = {}
|
345
328
|
for response in method.returns
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
end
|
329
|
+
next unless response.code.to_s == return_code.to_s
|
330
|
+
schema = response_schema(response, allow_nulls)
|
331
|
+
schema[:definitions] = @definitions if @definitions != {}
|
332
|
+
return schema
|
351
333
|
end
|
352
334
|
nil
|
353
335
|
end
|
@@ -364,9 +346,22 @@ module Apipie
|
|
364
346
|
@disable_default_value_warning = true
|
365
347
|
|
366
348
|
if responses_use_reference? && response.typename
|
367
|
-
schema = {
|
349
|
+
schema = {
|
350
|
+
"$ref" => gen_referenced_block_from_params_array(
|
351
|
+
response.typename,
|
352
|
+
response.params_ordered,
|
353
|
+
allow_nulls
|
354
|
+
)
|
355
|
+
}
|
368
356
|
else
|
369
|
-
schema =
|
357
|
+
schema = Apipie::Generator::Swagger::ParamDescription::Composite.new(
|
358
|
+
response.params_ordered,
|
359
|
+
Apipie::Generator::Swagger::Context.new(
|
360
|
+
allow_null: allow_nulls,
|
361
|
+
http_method: @current_http_method,
|
362
|
+
controller_method: @current_method
|
363
|
+
)
|
364
|
+
).to_swagger
|
370
365
|
end
|
371
366
|
|
372
367
|
ensure
|
@@ -397,7 +392,7 @@ module Apipie
|
|
397
392
|
|
398
393
|
for response in method.returns
|
399
394
|
swagger_response_block = {
|
400
|
-
description: response.description
|
395
|
+
description: Apipie.app.translate(response.description, @current_lang)
|
401
396
|
}
|
402
397
|
|
403
398
|
schema = response_schema(response)
|
@@ -434,105 +429,14 @@ module Apipie
|
|
434
429
|
|
435
430
|
missing.each do |name|
|
436
431
|
warn_path_parameter_not_described(name, path)
|
437
|
-
result[name.to_sym] = OpenStruct.new({
|
438
|
-
required: true,
|
439
|
-
_gen_added_from_path: true,
|
440
|
-
name: name,
|
441
|
-
validator: Apipie::Validator::NumberValidator.new(nil),
|
442
|
-
options: {
|
443
|
-
in: "path"
|
444
|
-
}
|
445
|
-
})
|
446
|
-
end
|
447
|
-
|
448
|
-
result
|
449
|
-
end
|
450
|
-
|
451
|
-
#--------------------------------------------------------------------------
|
452
|
-
# The core routine for creating a swagger parameter definition block.
|
453
|
-
# The output is slightly different when the parameter is inside a schema block.
|
454
|
-
#--------------------------------------------------------------------------
|
455
|
-
def swagger_atomic_param(param_desc, in_schema, name, allow_nulls)
|
456
|
-
def save_field(entry, openapi_key, v, apipie_key=openapi_key, translate=false)
|
457
|
-
if v.key?(apipie_key)
|
458
|
-
if translate
|
459
|
-
entry[openapi_key] = Apipie.app.translate(v[apipie_key], @current_lang)
|
460
|
-
else
|
461
|
-
entry[openapi_key] = v[apipie_key]
|
462
|
-
end
|
463
|
-
end
|
464
|
-
end
|
465
|
-
|
466
|
-
swagger_def = {}
|
467
|
-
swagger_def[:name] = name if !name.nil?
|
468
|
-
|
469
|
-
swg_param_type = swagger_param_type(param_desc)
|
470
|
-
swagger_def[:type] = swg_param_type.to_s
|
471
|
-
if (swg_param_type.is_a? Apipie::Generator::Swagger::Type) && !swg_param_type.str_format.nil?
|
472
|
-
swagger_def[:format] = swg_param_type.str_format
|
473
|
-
end
|
474
|
-
|
475
|
-
if swagger_def[:type] == "array"
|
476
|
-
array_of_validator_opts = param_desc.validator.param_description.options
|
477
|
-
items_type = array_of_validator_opts[:of].to_s || array_of_validator_opts[:array_of].to_s
|
478
|
-
if items_type == "Hash"
|
479
|
-
ref_name = "#{swagger_op_id_for_path(param_desc.method_description.apis.first.http_method, param_desc.method_description.apis.first.path)}_param_#{param_desc.name}"
|
480
|
-
swagger_def[:items] = {"$ref" => gen_referenced_block_from_params_array(ref_name, param_desc.validator.param_description.validator.params_ordered, allow_nulls)}
|
481
|
-
else
|
482
|
-
swagger_def[:items] = {type: "string"}
|
483
|
-
end
|
484
|
-
|
485
|
-
enum = param_desc.options.fetch(:in, [])
|
486
|
-
swagger_def[:items][:enum] = enum if enum.any?
|
487
|
-
end
|
488
|
-
|
489
|
-
if swagger_def[:type] == "enum"
|
490
|
-
swagger_def[:type] = "string"
|
491
|
-
swagger_def[:enum] = param_desc.validator.values
|
492
|
-
end
|
493
432
|
|
494
|
-
|
495
|
-
|
496
|
-
warn_hash_without_internal_typespec(param_desc.name)
|
433
|
+
result[name.to_sym] = Apipie::Generator::Swagger::ParamDescription.
|
434
|
+
create_for_missing_param(method, name)
|
497
435
|
end
|
498
436
|
|
499
|
-
|
500
|
-
new_swagger_def = {
|
501
|
-
items: swagger_def,
|
502
|
-
type: 'array'
|
503
|
-
}
|
504
|
-
swagger_def = new_swagger_def
|
505
|
-
if allow_nulls
|
506
|
-
swagger_def[:type] = [swagger_def[:type], "null"]
|
507
|
-
end
|
508
|
-
end
|
509
|
-
|
510
|
-
if allow_nulls
|
511
|
-
swagger_def[:type] = [swagger_def[:type], "null"]
|
512
|
-
end
|
513
|
-
|
514
|
-
if !in_schema
|
515
|
-
# the "name" and "in" keys can only be set on root parameters (non-nested)
|
516
|
-
swagger_def[:in] = @default_value_for_param_in if name.present?
|
517
|
-
swagger_def[:required] = param_desc.required if param_desc.required
|
518
|
-
end
|
519
|
-
|
520
|
-
save_field(swagger_def, :description, param_desc.options, :desc, true) unless param_desc.options[:desc].nil?
|
521
|
-
save_field(swagger_def, :default, param_desc.options, :default_value)
|
522
|
-
|
523
|
-
if param_desc.respond_to?(:_gen_added_from_path) && !param_desc.required
|
524
|
-
warn_optional_param_in_path(param_desc.name)
|
525
|
-
swagger_def[:required] = true
|
526
|
-
end
|
527
|
-
|
528
|
-
if !swagger_def[:required] && !swagger_def.key?(:default)
|
529
|
-
warn_optional_without_default_value(param_desc.name) unless @disable_default_value_warning
|
530
|
-
end
|
531
|
-
|
532
|
-
swagger_def
|
437
|
+
result
|
533
438
|
end
|
534
439
|
|
535
|
-
|
536
440
|
#--------------------------------------------------------------------------
|
537
441
|
# JSON schema and referenced-object generation
|
538
442
|
#--------------------------------------------------------------------------
|
@@ -541,79 +445,24 @@ module Apipie
|
|
541
445
|
"#/definitions/#{name}"
|
542
446
|
end
|
543
447
|
|
544
|
-
|
545
|
-
def json_schema_obj_from_params_array(params_array, allow_nulls = false)
|
546
|
-
(param_defs, required_params) = json_schema_param_defs_from_params_array(params_array, allow_nulls)
|
547
|
-
|
548
|
-
result = {type: "object"}
|
549
|
-
result[:properties] = param_defs
|
550
|
-
result[:additionalProperties] = false unless Apipie.configuration.swagger_allow_additional_properties_in_response
|
551
|
-
result[:required] = required_params if required_params.length > 0
|
552
|
-
|
553
|
-
param_defs.length > 0 ? result : nil
|
554
|
-
end
|
555
|
-
|
556
448
|
def gen_referenced_block_from_params_array(name, params_array, allow_nulls=false)
|
557
449
|
return ref_to(:name) if @definitions.key(:name)
|
558
450
|
|
559
|
-
schema_obj =
|
451
|
+
schema_obj = Apipie::Generator::Swagger::ParamDescription::Composite.new(
|
452
|
+
params_array,
|
453
|
+
Apipie::Generator::Swagger::Context.new(
|
454
|
+
allow_null: allow_nulls,
|
455
|
+
http_method: @current_http_method,
|
456
|
+
controller_method: @current_method
|
457
|
+
)
|
458
|
+
).to_swagger
|
459
|
+
|
560
460
|
return nil if schema_obj.nil?
|
561
461
|
|
562
462
|
@definitions[name.to_sym] = schema_obj
|
563
463
|
ref_to(name.to_sym)
|
564
464
|
end
|
565
465
|
|
566
|
-
def json_schema_param_defs_from_params_array(params_array, allow_nulls = false)
|
567
|
-
param_defs = {}
|
568
|
-
required_params = []
|
569
|
-
|
570
|
-
params_array ||= []
|
571
|
-
|
572
|
-
|
573
|
-
for param_desc in params_array
|
574
|
-
if !param_desc.respond_to?(:required)
|
575
|
-
# pp param_desc
|
576
|
-
raise ("unexpected param_desc format")
|
577
|
-
end
|
578
|
-
|
579
|
-
required_params.push(param_desc.name.to_sym) if param_desc.required
|
580
|
-
|
581
|
-
param_type = swagger_param_type(param_desc)
|
582
|
-
|
583
|
-
if param_type == "object" && param_desc.validator.params_ordered
|
584
|
-
schema = json_schema_obj_from_params_array(param_desc.validator.params_ordered, allow_nulls)
|
585
|
-
if param_desc.additional_properties
|
586
|
-
schema[:additionalProperties] = true
|
587
|
-
end
|
588
|
-
|
589
|
-
if param_desc.is_array?
|
590
|
-
new_schema = {
|
591
|
-
type: 'array',
|
592
|
-
items: schema
|
593
|
-
}
|
594
|
-
schema = new_schema
|
595
|
-
end
|
596
|
-
|
597
|
-
if allow_nulls
|
598
|
-
# ideally we would write schema[:type] = ["object", "null"]
|
599
|
-
# but due to a bug in the json-schema gem, we need to use anyOf
|
600
|
-
# see https://github.com/ruby-json-schema/json-schema/issues/404
|
601
|
-
new_schema = {
|
602
|
-
anyOf: [schema, {type: "null"}]
|
603
|
-
}
|
604
|
-
schema = new_schema
|
605
|
-
end
|
606
|
-
param_defs[param_desc.name.to_sym] = schema if !schema.nil?
|
607
|
-
else
|
608
|
-
param_defs[param_desc.name.to_sym] = swagger_atomic_param(param_desc, true, nil, allow_nulls)
|
609
|
-
end
|
610
|
-
end
|
611
|
-
|
612
|
-
[param_defs, required_params]
|
613
|
-
end
|
614
|
-
|
615
|
-
|
616
|
-
|
617
466
|
#--------------------------------------------------------------------------
|
618
467
|
# swagger "Params" block generation
|
619
468
|
#--------------------------------------------------------------------------
|
@@ -638,7 +487,15 @@ module Apipie
|
|
638
487
|
if params_in_body_use_reference?
|
639
488
|
swagger_schema_for_body = {"$ref" => gen_referenced_block_from_params_array("#{swagger_op_id_for_method(method)}_input", body_param_defs_array)}
|
640
489
|
else
|
641
|
-
swagger_schema_for_body =
|
490
|
+
swagger_schema_for_body =
|
491
|
+
Apipie::Generator::Swagger::ParamDescription::Composite.new(
|
492
|
+
body_param_defs_array,
|
493
|
+
Apipie::Generator::Swagger::Context.new(
|
494
|
+
allow_null: false,
|
495
|
+
http_method: @current_http_method,
|
496
|
+
controller_method: @current_method
|
497
|
+
)
|
498
|
+
).to_swagger
|
642
499
|
end
|
643
500
|
|
644
501
|
swagger_body_param = {
|
@@ -675,20 +532,7 @@ module Apipie
|
|
675
532
|
|
676
533
|
|
677
534
|
def add_params_from_hash(swagger_params_array, param_defs, prefix=nil, default_value_for_in=nil)
|
678
|
-
|
679
|
-
if default_value_for_in
|
680
|
-
@default_value_for_param_in = default_value_for_in
|
681
|
-
else
|
682
|
-
if body_allowed_for_current_method
|
683
|
-
@default_value_for_param_in = "formData"
|
684
|
-
else
|
685
|
-
@default_value_for_param_in = "query"
|
686
|
-
end
|
687
|
-
end
|
688
|
-
|
689
|
-
|
690
535
|
param_defs.each do |name, desc|
|
691
|
-
|
692
536
|
if !prefix.nil?
|
693
537
|
name = "#{prefix}[#{name}]"
|
694
538
|
end
|
@@ -701,13 +545,21 @@ module Apipie
|
|
701
545
|
warn_param_ignored_in_form_data(desc.name)
|
702
546
|
end
|
703
547
|
else
|
704
|
-
param_entry =
|
548
|
+
param_entry = Apipie::Generator::Swagger::ParamDescription::Builder.
|
549
|
+
new(desc, in_schema: false, controller_method: @current_method).
|
550
|
+
with_description(language: @current_lang).
|
551
|
+
with_name(prefix: prefix).
|
552
|
+
with_type(with_null: @allow_null).
|
553
|
+
with_in(
|
554
|
+
http_method: @current_http_method,
|
555
|
+
default_in_value: default_value_for_in
|
556
|
+
).to_swagger
|
557
|
+
|
705
558
|
if param_entry[:required]
|
706
559
|
swagger_params_array.unshift(param_entry)
|
707
560
|
else
|
708
561
|
swagger_params_array.push(param_entry)
|
709
562
|
end
|
710
|
-
|
711
563
|
end
|
712
564
|
end
|
713
565
|
end
|
data/lib/apipie/validator.rb
CHANGED
@@ -347,10 +347,10 @@ module Apipie
|
|
347
347
|
if @hash_params
|
348
348
|
@hash_params.each do |k, p|
|
349
349
|
if Apipie.configuration.validate_presence?
|
350
|
-
raise ParamMissing.new(p) if p.required && !value.
|
350
|
+
raise ParamMissing.new(p) if p.required && !value.key?(k)
|
351
351
|
end
|
352
352
|
if Apipie.configuration.validate_value?
|
353
|
-
p.validate(value[k]) if value.
|
353
|
+
p.validate(value[k]) if value.key?(k)
|
354
354
|
end
|
355
355
|
end
|
356
356
|
end
|
@@ -360,7 +360,7 @@ module Apipie
|
|
360
360
|
def process_value(value)
|
361
361
|
if @hash_params && value
|
362
362
|
return @hash_params.each_with_object({}) do |(key, param), api_params|
|
363
|
-
if value.
|
363
|
+
if value.key?(key)
|
364
364
|
api_params[param.as] = param.process_value(value[key])
|
365
365
|
end
|
366
366
|
end
|