apipie-rails 0.9.4 → 1.0.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/.rubocop.yml +8 -14
- data/.rubocop_todo.yml +102 -213
- data/CHANGELOG.md +17 -6
- data/README.rst +12 -12
- data/app/controllers/apipie/apipies_controller.rb +4 -4
- data/lib/apipie/apipie_module.rb +4 -4
- data/lib/apipie/application.rb +70 -54
- data/lib/apipie/configuration.rb +19 -26
- data/lib/apipie/dsl_definition.rb +4 -5
- data/lib/apipie/extractor/collector.rb +2 -2
- data/lib/apipie/extractor.rb +1 -1
- data/lib/apipie/generator/config.rb +12 -0
- data/lib/apipie/generator/swagger/computed_interface_id.rb +23 -0
- data/lib/apipie/generator/swagger/config.rb +78 -0
- data/lib/apipie/generator/swagger/context.rb +12 -1
- data/lib/apipie/generator/swagger/method_description/api_decorator.rb +20 -0
- data/lib/apipie/generator/swagger/method_description/api_schema_service.rb +86 -0
- data/lib/apipie/generator/swagger/method_description/decorator.rb +22 -0
- data/lib/apipie/generator/swagger/method_description/parameters_service.rb +139 -0
- data/lib/apipie/generator/swagger/method_description/response_schema_service.rb +46 -0
- data/lib/apipie/generator/swagger/method_description/response_service.rb +58 -0
- data/lib/apipie/generator/swagger/method_description.rb +2 -0
- data/lib/apipie/generator/swagger/operation_id.rb +1 -1
- data/lib/apipie/generator/swagger/param_description/builder.rb +4 -4
- data/lib/apipie/generator/swagger/param_description/composite.rb +9 -1
- data/lib/apipie/generator/swagger/param_description/in.rb +1 -1
- data/lib/apipie/generator/swagger/param_description/path_params_composite.rb +61 -0
- data/lib/apipie/generator/swagger/param_description/referenced_composite.rb +36 -0
- data/lib/apipie/generator/swagger/param_description/type.rb +9 -2
- data/lib/apipie/generator/swagger/path_decorator.rb +36 -0
- data/lib/apipie/generator/swagger/referenced_definitions.rb +17 -0
- data/lib/apipie/generator/swagger/resource_description_collection.rb +30 -0
- data/lib/apipie/generator/swagger/resource_description_composite.rb +56 -0
- data/lib/apipie/generator/swagger/schema.rb +63 -0
- data/lib/apipie/generator/swagger/type_extractor.rb +0 -19
- data/lib/apipie/generator/swagger/warning.rb +3 -6
- data/lib/apipie/generator/swagger/warning_writer.rb +7 -1
- data/lib/apipie/method_description.rb +4 -2
- data/lib/apipie/param_description.rb +4 -2
- data/lib/apipie/resource_description.rb +1 -1
- data/lib/apipie/swagger_generator.rb +27 -551
- data/lib/apipie/validator.rb +7 -3
- data/lib/apipie/version.rb +1 -1
- data/lib/apipie-rails.rb +17 -0
- data/lib/tasks/apipie.rake +15 -10
- data/spec/controllers/api/v2/nested/resources_controller_spec.rb +2 -2
- data/spec/controllers/pets_controller_spec.rb +10 -16
- data/spec/controllers/users_controller_spec.rb +2 -2
- data/spec/dummy/app/controllers/pets_controller.rb +4 -4
- data/spec/dummy/app/controllers/pets_using_self_describing_classes_controller.rb +2 -2
- data/spec/dummy/app/controllers/twitter_example_controller.rb +2 -2
- data/spec/dummy/app/controllers/users_controller.rb +5 -5
- data/spec/lib/apipie/application_spec.rb +16 -7
- data/spec/lib/apipie/configuration_spec.rb +15 -0
- data/spec/lib/apipie/generator/swagger/config_spec.rb +19 -0
- data/spec/lib/apipie/generator/swagger/context_spec.rb +22 -2
- data/spec/lib/apipie/generator/swagger/method_description/api_schema_service_spec.rb +106 -0
- data/spec/lib/apipie/generator/swagger/method_description/response_schema_service_spec.rb +105 -0
- data/spec/lib/apipie/generator/swagger/param_description/builder_spec.rb +1 -1
- data/spec/lib/apipie/generator/swagger/param_description/composite_spec.rb +2 -2
- data/spec/lib/apipie/generator/swagger/param_description/type_spec.rb +7 -7
- data/spec/lib/apipie/generator/swagger/path_decorator_spec.rb +57 -0
- data/spec/lib/apipie/generator/swagger/referenced_definitions_spec.rb +35 -0
- data/spec/lib/apipie/generator/swagger/resource_description_composite_spec.rb +37 -0
- data/spec/lib/apipie/generator/swagger/resource_descriptions_collection_spec.rb +57 -0
- data/spec/lib/apipie/generator/swagger/schema_spec.rb +89 -0
- data/spec/lib/apipie/generator/swagger/type_extractor_spec.rb +0 -43
- data/spec/lib/apipie/generator/swagger/warning_spec.rb +1 -1
- data/spec/lib/apipie/generator/swagger/warning_writer_spec.rb +19 -7
- data/spec/lib/apipie/method_description_spec.rb +101 -66
- data/spec/lib/apipie/param_description_spec.rb +209 -49
- data/spec/lib/apipie/param_group_spec.rb +1 -0
- data/spec/lib/apipie/resource_description_spec.rb +1 -1
- data/spec/lib/apipie/swagger_generator_spec.rb +94 -0
- data/spec/lib/apipie/validator_spec.rb +47 -11
- data/spec/lib/swagger/rake_swagger_spec.rb +4 -4
- data/spec/lib/swagger/swagger_dsl_spec.rb +7 -7
- data/spec/lib/validators/array_validator_spec.rb +1 -1
- metadata +28 -2
@@ -1,569 +1,45 @@
|
|
1
1
|
module Apipie
|
2
|
-
|
3
|
-
#--------------------------------------------------------------------------
|
4
|
-
# Configuration. Should be moved to Apipie config.
|
5
|
-
#--------------------------------------------------------------------------
|
6
2
|
class SwaggerGenerator
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@apipie = apipie
|
16
|
-
@issued_warnings = []
|
17
|
-
end
|
18
|
-
|
19
|
-
def params_in_body?
|
20
|
-
Apipie.configuration.swagger_content_type_input == :json
|
21
|
-
end
|
22
|
-
|
23
|
-
def params_in_body_use_reference?
|
24
|
-
Apipie.configuration.swagger_json_input_uses_refs
|
25
|
-
end
|
26
|
-
|
27
|
-
def responses_use_reference?
|
28
|
-
Apipie.configuration.swagger_responses_use_refs?
|
29
|
-
end
|
30
|
-
|
31
|
-
def include_warning_tags?
|
32
|
-
Apipie.configuration.swagger_include_warning_tags
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
def generate_from_resources(version, resources, method_name, lang, clear_warnings = false)
|
37
|
-
init_swagger_vars(version, lang, clear_warnings)
|
38
|
-
|
39
|
-
@only_method = method_name
|
40
|
-
add_resources(resources)
|
41
|
-
|
42
|
-
@swagger[:info]["x-computed-id"] = @computed_interface_id if Apipie.configuration.swagger_generate_x_computed_id_field?
|
43
|
-
return @swagger
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
#--------------------------------------------------------------------------
|
48
|
-
# Initialization
|
49
|
-
#--------------------------------------------------------------------------
|
50
|
-
|
51
|
-
def init_swagger_vars(version, lang, clear_warnings = false)
|
52
|
-
|
53
|
-
# docs = {
|
54
|
-
# :name => Apipie.configuration.app_name,
|
55
|
-
# :info => Apipie.app_info(version, lang),
|
56
|
-
# :copyright => Apipie.configuration.copyright,
|
57
|
-
# :doc_url => Apipie.full_url(url_args),
|
58
|
-
# :api_url => Apipie.api_base_url(version),
|
59
|
-
# :resources => _resources
|
60
|
-
# }
|
61
|
-
|
62
|
-
|
63
|
-
@swagger = {
|
64
|
-
swagger: '2.0',
|
65
|
-
info: {
|
66
|
-
title: "#{Apipie.configuration.app_name}",
|
67
|
-
description: "#{Apipie.app_info(version, lang)}#{Apipie.configuration.copyright}",
|
68
|
-
version: "#{version}",
|
69
|
-
"x-copyright" => Apipie.configuration.copyright,
|
70
|
-
},
|
71
|
-
basePath: Apipie.api_base_url(version),
|
72
|
-
consumes: [],
|
73
|
-
paths: {},
|
74
|
-
definitions: {},
|
75
|
-
schemes: Apipie.configuration.swagger_schemes,
|
76
|
-
tags: [],
|
77
|
-
securityDefinitions: Apipie.configuration.swagger_security_definitions,
|
78
|
-
security: Apipie.configuration.swagger_global_security
|
79
|
-
}
|
80
|
-
|
81
|
-
if Apipie.configuration.swagger_api_host
|
82
|
-
@swagger[:host] = Apipie.configuration.swagger_api_host
|
83
|
-
end
|
84
|
-
|
85
|
-
if params_in_body?
|
86
|
-
@swagger[:consumes] = ['application/json']
|
87
|
-
@swagger[:info][:title] += " (params in:body)"
|
88
|
-
else
|
89
|
-
@swagger[:consumes] = ['application/x-www-form-urlencoded', 'multipart/form-data']
|
90
|
-
@swagger[:info][:title] += " (params in:formData)"
|
91
|
-
end
|
92
|
-
|
93
|
-
@paths = @swagger[:paths]
|
94
|
-
@definitions = @swagger[:definitions]
|
95
|
-
@tags = @swagger[:tags]
|
96
|
-
|
97
|
-
@issued_warnings = [] if clear_warnings || @issued_warnings.nil?
|
98
|
-
@computed_interface_id = 0
|
99
|
-
|
100
|
-
@current_lang = lang
|
101
|
-
end
|
102
|
-
|
103
|
-
#--------------------------------------------------------------------------
|
104
|
-
# Engine interface methods
|
105
|
-
#--------------------------------------------------------------------------
|
106
|
-
|
107
|
-
def add_resources(resources)
|
108
|
-
resources.each do |resource_name, resource_defs|
|
109
|
-
add_resource_description(resource_name, resource_defs)
|
110
|
-
add_resource_methods(resource_name, resource_defs)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def add_resource_methods(resource_name, resource_defs)
|
115
|
-
resource_defs._methods.each do |apipie_method_name, apipie_method_defs|
|
116
|
-
add_ruby_method(@paths, apipie_method_defs)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
|
121
|
-
#--------------------------------------------------------------------------
|
122
|
-
# Logging, debugging and regression-testing utilities
|
123
|
-
#--------------------------------------------------------------------------
|
124
|
-
|
125
|
-
def ruby_name_for_method(method)
|
126
|
-
return "<no method>" if method.nil?
|
127
|
-
method.resource.controller.name + "#" + method.method
|
128
|
-
end
|
129
|
-
|
130
|
-
def warn_missing_method_summary
|
131
|
-
warn(Apipie::Generator::Swagger::Warning::MISSING_METHOD_SUMMARY_CODE)
|
132
|
-
end
|
133
|
-
|
134
|
-
def warn_added_missing_slash(path)
|
135
|
-
warn(
|
136
|
-
Apipie::Generator::Swagger::Warning::ADDED_MISSING_SLASH_CODE,
|
137
|
-
{ path: path }
|
138
|
-
)
|
139
|
-
end
|
140
|
-
|
141
|
-
def warn_no_return_codes_specified
|
142
|
-
warn(Apipie::Generator::Swagger::Warning::NO_RETURN_CODES_SPECIFIED_CODE)
|
143
|
-
end
|
144
|
-
|
145
|
-
def warn_optional_param_in_path(param_name)
|
146
|
-
warn(
|
147
|
-
Apipie::Generator::Swagger::Warning::OPTIONAL_PARAM_IN_PATH_CODE,
|
148
|
-
{ parameter: param_name }
|
149
|
-
)
|
150
|
-
end
|
151
|
-
|
152
|
-
def warn_optional_without_default_value(param_name)
|
153
|
-
warn(
|
154
|
-
Apipie::Generator::Swagger::Warning::OPTIONAL_WITHOUT_DEFAULT_VALUE_CODE,
|
155
|
-
{ parameter: param_name }
|
156
|
-
)
|
157
|
-
end
|
158
|
-
|
159
|
-
def warn_param_ignored_in_form_data(param_name)
|
160
|
-
warn(
|
161
|
-
Apipie::Generator::Swagger::Warning::PARAM_IGNORED_IN_FORM_DATA_CODE,
|
162
|
-
{ parameter: param_name }
|
163
|
-
)
|
164
|
-
end
|
165
|
-
|
166
|
-
def warn_path_parameter_not_described(name, path)
|
167
|
-
warn(
|
168
|
-
Apipie::Generator::Swagger::Warning::PATH_PARAM_NOT_DESCRIBED_CODE,
|
169
|
-
{ name: name, path: path }
|
170
|
-
)
|
171
|
-
end
|
172
|
-
|
173
|
-
def warn_inferring_boolean(name)
|
174
|
-
warn(
|
175
|
-
Apipie::Generator::Swagger::Warning::INFERRING_BOOLEAN_CODE,
|
176
|
-
{ name: name }
|
177
|
-
)
|
178
|
-
end
|
179
|
-
|
180
|
-
# @param [Integer] warning_code
|
181
|
-
# @param [Hash] message_attributes
|
182
|
-
def warn(warning_code, message_attributes = {})
|
183
|
-
Apipie::Generator::Swagger::Warning.for_code(
|
184
|
-
warning_code,
|
185
|
-
ruby_name_for_method(@current_method),
|
186
|
-
message_attributes
|
187
|
-
).warn_through_writer
|
188
|
-
|
189
|
-
@warnings_issued = Apipie::Generator::Swagger::WarningWriter.
|
190
|
-
instance.
|
191
|
-
issued_warnings?
|
192
|
-
end
|
193
|
-
|
194
|
-
def info(msg)
|
195
|
-
print "--- INFO: [#{ruby_name_for_method(@current_method)}] -- #{msg}\n"
|
196
|
-
end
|
197
|
-
|
198
|
-
|
199
|
-
# the @computed_interface_id is a number that is uniquely derived from the list of operations
|
200
|
-
# added to the swagger definition (in an order-dependent way).
|
201
|
-
# it can be used for regression testing, allowing some differentiation between changes that
|
202
|
-
# result from changes to the input and those that result from changes to the generation
|
203
|
-
# algorithms.
|
204
|
-
# note that at the moment, this only takes operation ids into account, and ignores parameter
|
205
|
-
# definitions, so it's only partially useful.
|
206
|
-
def include_op_id_in_computed_interface_id(op_id)
|
207
|
-
@computed_interface_id = Zlib::crc32("#{@computed_interface_id} #{op_id}") if Apipie.configuration.swagger_generate_x_computed_id_field?
|
208
|
-
end
|
209
|
-
|
210
|
-
#--------------------------------------------------------------------------
|
211
|
-
# Create a tag description for a described resource
|
212
|
-
#--------------------------------------------------------------------------
|
213
|
-
|
214
|
-
def tag_name_for_resource(resource)
|
215
|
-
# resource.controller
|
216
|
-
resource._id
|
217
|
-
end
|
218
|
-
|
219
|
-
def add_resource_description(resource_name, resource)
|
220
|
-
if resource._full_description
|
221
|
-
@tags << {
|
222
|
-
name: tag_name_for_resource(resource),
|
223
|
-
description: Apipie.app.translate(resource._full_description, @current_lang)
|
224
|
-
}
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
#--------------------------------------------------------------------------
|
229
|
-
# Create swagger definitions for a ruby method
|
230
|
-
#--------------------------------------------------------------------------
|
231
|
-
|
232
|
-
def add_ruby_method(paths, ruby_method)
|
233
|
-
|
234
|
-
if @only_method
|
235
|
-
return unless ruby_method.method == @only_method
|
236
|
-
else
|
237
|
-
return if !ruby_method.show
|
238
|
-
end
|
239
|
-
|
240
|
-
for api in ruby_method.apis do
|
241
|
-
# controller: ruby_method.resource.controller.name,
|
242
|
-
|
243
|
-
path = swagger_path(api.path)
|
244
|
-
paths[path] ||= {}
|
245
|
-
methods = paths[path]
|
246
|
-
@current_method = ruby_method
|
247
|
-
|
248
|
-
@warnings_issued = false
|
249
|
-
responses = swagger_responses_hash_for_method(ruby_method)
|
250
|
-
if include_warning_tags?
|
251
|
-
warning_tags = @warnings_issued ? ['warnings issued'] : []
|
252
|
-
else
|
253
|
-
warning_tags = []
|
254
|
-
end
|
255
|
-
|
256
|
-
op_id = Apipie::Generator::Swagger::OperationId.from(api).to_s
|
257
|
-
|
258
|
-
include_op_id_in_computed_interface_id(op_id)
|
259
|
-
|
260
|
-
method_key = api.http_method.downcase
|
261
|
-
@current_http_method = method_key
|
262
|
-
|
263
|
-
methods[method_key] = {
|
264
|
-
tags: [tag_name_for_resource(ruby_method.resource)] + warning_tags + ruby_method.tag_list.tags,
|
265
|
-
consumes: params_in_body? ? ['application/json'] : ['application/x-www-form-urlencoded', 'multipart/form-data'],
|
266
|
-
operationId: op_id,
|
267
|
-
summary: Apipie.app.translate(api.short_description, @current_lang),
|
268
|
-
parameters: swagger_params_array_for_method(ruby_method, api.path),
|
269
|
-
responses: responses,
|
270
|
-
description: Apipie.app.translate(ruby_method.full_description, @current_lang)
|
271
|
-
}
|
272
|
-
|
273
|
-
if methods[method_key][:summary].nil?
|
274
|
-
methods[method_key].delete(:summary)
|
275
|
-
warn_missing_method_summary
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
end
|
280
|
-
|
281
|
-
#--------------------------------------------------------------------------
|
282
|
-
# Utilities for conversion of ruby syntax to swagger syntax
|
283
|
-
#--------------------------------------------------------------------------
|
284
|
-
|
285
|
-
def swagger_path(str)
|
286
|
-
str = str.gsub(/:(\w+)/, '{\1}')
|
287
|
-
str = str.gsub(%r{/$}, '')
|
288
|
-
|
289
|
-
if str[0] != '/'
|
290
|
-
warn_added_missing_slash(str)
|
291
|
-
str = '/' + str
|
292
|
-
end
|
293
|
-
str
|
294
|
-
end
|
295
|
-
|
296
|
-
def remove_colons(str)
|
297
|
-
str.gsub(":", "_")
|
298
|
-
end
|
299
|
-
|
300
|
-
def swagger_op_id_for_method(method)
|
301
|
-
remove_colons method.resource.controller.name + "::" + method.method
|
302
|
-
end
|
303
|
-
|
304
|
-
def swagger_param_type(param_desc)
|
305
|
-
if param_desc.blank?
|
306
|
-
raise ArgumentError, 'param_desc is required'
|
307
|
-
end
|
308
|
-
|
309
|
-
method_id = ruby_name_for_method(@current_method)
|
310
|
-
|
311
|
-
warning = Apipie::Generator::Swagger::Warning.for_code(
|
312
|
-
Apipie::Generator::Swagger::Warning::INFERRING_BOOLEAN_CODE,
|
313
|
-
method_id,
|
314
|
-
{ parameter: param_desc.name }
|
315
|
-
)
|
316
|
-
|
317
|
-
Apipie::Generator::Swagger::TypeExtractor.new(param_desc.validator).
|
318
|
-
extract_with_warnings({ boolean: warning })
|
319
|
-
end
|
320
|
-
|
321
|
-
|
322
|
-
#--------------------------------------------------------------------------
|
323
|
-
# Responses
|
324
|
-
#--------------------------------------------------------------------------
|
325
|
-
|
326
|
-
def json_schema_for_method_response(method, return_code, allow_nulls)
|
327
|
-
@definitions = {}
|
328
|
-
for response in method.returns
|
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
|
333
|
-
end
|
334
|
-
nil
|
3
|
+
# @param [Array<Apipie::ResourceDescription] resources
|
4
|
+
def self.generate_from_resources(resources, version:, language:, clear_warnings: false)
|
5
|
+
Apipie::Generator::Swagger::Schema.new(
|
6
|
+
resources,
|
7
|
+
version: version,
|
8
|
+
language: language,
|
9
|
+
clear_warnings: clear_warnings
|
10
|
+
).generate
|
335
11
|
end
|
336
12
|
|
337
|
-
def
|
338
|
-
|
339
|
-
response_schema(adapter, allow_nulls)
|
340
|
-
end
|
13
|
+
def self.json_schema_for_method_response(method, return_code, allow_nulls)
|
14
|
+
response = method.returns.find { |response| response.code.to_s == return_code.to_s }
|
341
15
|
|
342
|
-
|
343
|
-
begin
|
344
|
-
# no need to warn about "missing default value for optional param" when processing response definitions
|
345
|
-
prev_value = @disable_default_value_warning
|
346
|
-
@disable_default_value_warning = true
|
16
|
+
return if response.blank?
|
347
17
|
|
348
|
-
|
349
|
-
schema = {
|
350
|
-
"$ref" => gen_referenced_block_from_params_array(
|
351
|
-
response.typename,
|
352
|
-
response.params_ordered,
|
353
|
-
allow_nulls
|
354
|
-
)
|
355
|
-
}
|
356
|
-
else
|
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
|
365
|
-
end
|
18
|
+
http_method = method.apis.first.http_method
|
366
19
|
|
367
|
-
|
368
|
-
|
369
|
-
|
20
|
+
schema = Apipie::Generator::Swagger::MethodDescription::ResponseSchemaService.new(
|
21
|
+
response,
|
22
|
+
allow_null: allow_nulls,
|
23
|
+
http_method: http_method,
|
24
|
+
controller_method: method
|
25
|
+
).to_swagger
|
370
26
|
|
371
|
-
|
372
|
-
schema = {
|
373
|
-
type: allow_nulls ? ["array","null"] : "array",
|
374
|
-
items: schema
|
375
|
-
}
|
376
|
-
end
|
27
|
+
definitions = Apipie::Generator::Swagger::ReferencedDefinitions.instance.definitions
|
377
28
|
|
378
|
-
if
|
379
|
-
schema[:
|
29
|
+
if definitions.present?
|
30
|
+
schema[:definitions] = definitions
|
380
31
|
end
|
381
32
|
|
382
33
|
schema
|
383
34
|
end
|
384
35
|
|
385
|
-
def
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
end
|
392
|
-
|
393
|
-
for response in method.returns
|
394
|
-
swagger_response_block = {
|
395
|
-
description: Apipie.app.translate(response.description, @current_lang)
|
396
|
-
}
|
397
|
-
|
398
|
-
schema = response_schema(response)
|
399
|
-
swagger_response_block[:schema] = schema if schema
|
400
|
-
|
401
|
-
result[response.code] = swagger_response_block
|
402
|
-
end
|
403
|
-
|
404
|
-
if result.length == 0
|
405
|
-
warn_no_return_codes_specified
|
406
|
-
result[200] = {description: 'ok'}
|
407
|
-
end
|
408
|
-
|
409
|
-
result
|
410
|
-
end
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
#--------------------------------------------------------------------------
|
415
|
-
# Auto-insertion of parameters that are implicitly defined in the path
|
416
|
-
#--------------------------------------------------------------------------
|
417
|
-
|
418
|
-
def param_names_from_path(path)
|
419
|
-
path.scan(/:(\w+)/).map do |ar|
|
420
|
-
ar[0].to_sym
|
421
|
-
end
|
422
|
-
end
|
423
|
-
|
424
|
-
def add_missing_params(method, path)
|
425
|
-
param_names_from_method = method.params.map {|name, desc| name}
|
426
|
-
missing = param_names_from_path(path) - param_names_from_method
|
427
|
-
|
428
|
-
result = method.params
|
429
|
-
|
430
|
-
missing.each do |name|
|
431
|
-
warn_path_parameter_not_described(name, path)
|
432
|
-
|
433
|
-
result[name.to_sym] = Apipie::Generator::Swagger::ParamDescription.
|
434
|
-
create_for_missing_param(method, name)
|
435
|
-
end
|
436
|
-
|
437
|
-
result
|
438
|
-
end
|
439
|
-
|
440
|
-
#--------------------------------------------------------------------------
|
441
|
-
# JSON schema and referenced-object generation
|
442
|
-
#--------------------------------------------------------------------------
|
443
|
-
|
444
|
-
def ref_to(name)
|
445
|
-
"#/definitions/#{name}"
|
446
|
-
end
|
447
|
-
|
448
|
-
def gen_referenced_block_from_params_array(name, params_array, allow_nulls = false)
|
449
|
-
return ref_to(:name) if @definitions.key(:name)
|
450
|
-
|
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
|
-
)
|
36
|
+
def self.json_schema_for_self_describing_class(cls, allow_nulls)
|
37
|
+
Apipie::Generator::Swagger::MethodDescription::ResponseSchemaService.new(
|
38
|
+
ResponseDescriptionAdapter.from_self_describing_class(cls),
|
39
|
+
allow_null: allow_nulls,
|
40
|
+
http_method: nil,
|
41
|
+
controller_method: nil
|
458
42
|
).to_swagger
|
459
|
-
|
460
|
-
return nil if schema_obj.nil?
|
461
|
-
|
462
|
-
@definitions[name.to_sym] = schema_obj
|
463
|
-
ref_to(name.to_sym)
|
464
|
-
end
|
465
|
-
|
466
|
-
#--------------------------------------------------------------------------
|
467
|
-
# swagger "Params" block generation
|
468
|
-
#--------------------------------------------------------------------------
|
469
|
-
|
470
|
-
def body_allowed_for_current_method
|
471
|
-
!(['get', 'head'].include?(@current_http_method))
|
472
43
|
end
|
473
|
-
|
474
|
-
def swagger_params_array_for_method(method, path)
|
475
|
-
|
476
|
-
swagger_result = []
|
477
|
-
all_params_hash = add_missing_params(method, path)
|
478
|
-
|
479
|
-
body_param_defs_array = all_params_hash.map {|k, v| v if !param_names_from_path(path).include?(k)}.select{|v| !v.nil?}
|
480
|
-
body_param_defs_hash = all_params_hash.select {|k, v| v if !param_names_from_path(path).include?(k)}
|
481
|
-
path_param_defs_hash = all_params_hash.select {|k, v| v if param_names_from_path(path).include?(k)}
|
482
|
-
|
483
|
-
path_param_defs_hash.each{|name,desc| desc.required = true}
|
484
|
-
add_params_from_hash(swagger_result, path_param_defs_hash, nil, "path")
|
485
|
-
|
486
|
-
if params_in_body? && body_allowed_for_current_method
|
487
|
-
if params_in_body_use_reference?
|
488
|
-
swagger_schema_for_body = {"$ref" => gen_referenced_block_from_params_array("#{swagger_op_id_for_method(method)}_input", body_param_defs_array)}
|
489
|
-
else
|
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
|
499
|
-
end
|
500
|
-
|
501
|
-
swagger_body_param = {
|
502
|
-
name: 'body',
|
503
|
-
in: 'body',
|
504
|
-
schema: swagger_schema_for_body
|
505
|
-
}
|
506
|
-
swagger_result.push(swagger_body_param) if !swagger_schema_for_body.nil?
|
507
|
-
|
508
|
-
else
|
509
|
-
add_params_from_hash(swagger_result, body_param_defs_hash)
|
510
|
-
end
|
511
|
-
|
512
|
-
add_headers_from_hash(swagger_result, method.headers) if method.headers.present?
|
513
|
-
|
514
|
-
swagger_result
|
515
|
-
end
|
516
|
-
|
517
|
-
|
518
|
-
def add_headers_from_hash(swagger_params_array, headers)
|
519
|
-
swagger_headers = headers.map do |header|
|
520
|
-
header_hash = {
|
521
|
-
name: header[:name],
|
522
|
-
in: 'header',
|
523
|
-
required: header[:options][:required],
|
524
|
-
description: header[:description],
|
525
|
-
type: header[:options][:type] || 'string'
|
526
|
-
}
|
527
|
-
header_hash[:default] = header[:options][:default] if header[:options][:default]
|
528
|
-
header_hash
|
529
|
-
end
|
530
|
-
swagger_params_array.push(*swagger_headers)
|
531
|
-
end
|
532
|
-
|
533
|
-
|
534
|
-
def add_params_from_hash(swagger_params_array, param_defs, prefix = nil, default_value_for_in = nil)
|
535
|
-
param_defs.each do |name, desc|
|
536
|
-
if !prefix.nil?
|
537
|
-
name = "#{prefix}[#{name}]"
|
538
|
-
end
|
539
|
-
|
540
|
-
if swagger_param_type(desc) == "object"
|
541
|
-
if desc.validator.params_ordered
|
542
|
-
params_hash = Hash[desc.validator.params_ordered.map {|desc| [desc.name, desc]}]
|
543
|
-
add_params_from_hash(swagger_params_array, params_hash, name)
|
544
|
-
else
|
545
|
-
warn_param_ignored_in_form_data(desc.name)
|
546
|
-
end
|
547
|
-
else
|
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
|
-
|
558
|
-
if param_entry[:required]
|
559
|
-
swagger_params_array.unshift(param_entry)
|
560
|
-
else
|
561
|
-
swagger_params_array.push(param_entry)
|
562
|
-
end
|
563
|
-
end
|
564
|
-
end
|
565
|
-
end
|
566
|
-
|
567
44
|
end
|
568
|
-
|
569
45
|
end
|
data/lib/apipie/validator.rb
CHANGED
@@ -472,13 +472,13 @@ module Apipie
|
|
472
472
|
end
|
473
473
|
|
474
474
|
def self.build(param_description, argument, options, block)
|
475
|
-
if argument == :bool || argument == :boolean
|
475
|
+
if argument == :bool || argument == :boolean || boolean_array?(argument)
|
476
476
|
self.new(param_description)
|
477
477
|
end
|
478
478
|
end
|
479
479
|
|
480
|
-
def
|
481
|
-
|
480
|
+
private_class_method def self.boolean_array?(argument)
|
481
|
+
argument.is_a?(Array) && (argument - [true, false]) == []
|
482
482
|
end
|
483
483
|
|
484
484
|
def description
|
@@ -489,6 +489,10 @@ module Apipie
|
|
489
489
|
def ignore_allow_blank?
|
490
490
|
true
|
491
491
|
end
|
492
|
+
|
493
|
+
def expected_type
|
494
|
+
'boolean'
|
495
|
+
end
|
492
496
|
end
|
493
497
|
|
494
498
|
class NestedValidator < BaseValidator
|
data/lib/apipie/version.rb
CHANGED
data/lib/apipie-rails.rb
CHANGED
@@ -8,6 +8,7 @@ require "apipie/routing"
|
|
8
8
|
require "apipie/markup"
|
9
9
|
require "apipie/apipie_module"
|
10
10
|
require "apipie/dsl_definition"
|
11
|
+
require "apipie/generator/swagger/config"
|
11
12
|
require "apipie/configuration"
|
12
13
|
require "apipie/method_description"
|
13
14
|
require "apipie/resource_description"
|
@@ -27,17 +28,33 @@ require 'apipie/extractor'
|
|
27
28
|
require "apipie/version"
|
28
29
|
require "apipie/swagger_generator"
|
29
30
|
require "apipie/generator/generator"
|
31
|
+
require "apipie/generator/config"
|
30
32
|
require "apipie/generator/swagger/swagger"
|
33
|
+
require "apipie/generator/swagger/schema"
|
31
34
|
require "apipie/generator/swagger/operation_id"
|
32
35
|
require "apipie/generator/swagger/warning"
|
33
36
|
require "apipie/generator/swagger/warning_writer"
|
34
37
|
require "apipie/generator/swagger/type"
|
35
38
|
require "apipie/generator/swagger/type_extractor"
|
36
39
|
require "apipie/generator/swagger/context"
|
40
|
+
require "apipie/generator/swagger/computed_interface_id"
|
41
|
+
require "apipie/generator/swagger/path_decorator"
|
42
|
+
require "apipie/generator/swagger/referenced_definitions"
|
43
|
+
require "apipie/generator/swagger/resource_description_composite"
|
44
|
+
require "apipie/generator/swagger/resource_description_collection"
|
45
|
+
require "apipie/generator/swagger/method_description"
|
46
|
+
require "apipie/generator/swagger/method_description/parameters_service"
|
47
|
+
require "apipie/generator/swagger/method_description/response_service"
|
48
|
+
require "apipie/generator/swagger/method_description/response_schema_service"
|
49
|
+
require "apipie/generator/swagger/method_description/decorator"
|
50
|
+
require "apipie/generator/swagger/method_description/api_decorator"
|
51
|
+
require "apipie/generator/swagger/method_description/api_schema_service"
|
37
52
|
require "apipie/generator/swagger/param_description"
|
38
53
|
require "apipie/generator/swagger/param_description/builder"
|
39
54
|
require "apipie/generator/swagger/param_description/composite"
|
40
55
|
require "apipie/generator/swagger/param_description/description"
|
41
56
|
require "apipie/generator/swagger/param_description/in"
|
42
57
|
require "apipie/generator/swagger/param_description/name"
|
58
|
+
require "apipie/generator/swagger/param_description/path_params_composite"
|
59
|
+
require "apipie/generator/swagger/param_description/referenced_composite"
|
43
60
|
require "apipie/generator/swagger/param_description/type"
|