apipie-rails 0.9.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rubocop.yml +2 -2
- data/.rubocop.yml +23 -14
- data/.rubocop_todo.yml +103 -487
- data/CHANGELOG.md +20 -3
- data/README.rst +12 -12
- data/app/controllers/apipie/apipies_controller.rb +6 -6
- data/app/helpers/apipie_helper.rb +1 -1
- data/lib/apipie/apipie_module.rb +5 -5
- data/lib/apipie/application.rb +81 -55
- data/lib/apipie/configuration.rb +19 -26
- data/lib/apipie/dsl_definition.rb +8 -9
- data/lib/apipie/error_description.rb +1 -1
- data/lib/apipie/errors.rb +2 -16
- data/lib/apipie/extractor/collector.rb +3 -3
- data/lib/apipie/extractor/recorder.rb +1 -1
- data/lib/apipie/extractor.rb +2 -2
- 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 +2 -2
- 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/helpers.rb +3 -3
- data/lib/apipie/method_description.rb +5 -3
- data/lib/apipie/param_description.rb +4 -2
- data/lib/apipie/resource_description.rb +11 -8
- data/lib/apipie/response_description.rb +1 -1
- data/lib/apipie/response_description_adapter.rb +3 -3
- data/lib/apipie/routing.rb +1 -1
- data/lib/apipie/rspec/response_validation_helper.rb +1 -1
- data/lib/apipie/swagger_generator.rb +27 -551
- data/lib/apipie/validator.rb +9 -5
- data/lib/apipie/version.rb +1 -1
- data/lib/apipie-rails.rb +17 -0
- data/lib/tasks/apipie.rake +25 -20
- 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/dummy/config.ru +1 -1
- data/spec/lib/apipie/apipies_controller_spec.rb +4 -0
- data/spec/lib/apipie/application_spec.rb +25 -15
- 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 +23 -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/no_documented_method_spec.rb +17 -0
- 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 +71 -28
- data/spec/lib/apipie/response_does_not_match_swagger_schema_spec.rb +35 -0
- data/spec/lib/apipie/swagger_generator_spec.rb +94 -0
- data/spec/lib/apipie/validator_spec.rb +47 -11
- data/spec/lib/rake_spec.rb +1 -1
- data/spec/lib/swagger/rake_swagger_spec.rb +6 -6
- data/spec/lib/swagger/swagger_dsl_spec.rb +17 -11
- data/spec/lib/validators/array_validator_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- metadata +31 -3
@@ -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(/\/$/, '')
|
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
@@ -190,7 +190,7 @@ module Apipie
|
|
190
190
|
|
191
191
|
# arguments value must be an array
|
192
192
|
class ArrayValidator < Apipie::Validator::BaseValidator
|
193
|
-
def initialize(param_description, argument, options={})
|
193
|
+
def initialize(param_description, argument, options = {})
|
194
194
|
super(param_description)
|
195
195
|
@type = argument
|
196
196
|
@items_type = options[:of]
|
@@ -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,13 +489,17 @@ 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
|
495
499
|
|
496
500
|
def initialize(param_description, argument, param_group)
|
497
501
|
super(param_description)
|
498
|
-
@validator = Apipie::Validator::
|
502
|
+
@validator = Apipie::Validator::HashValidator.new(param_description, argument, param_group)
|
499
503
|
@type = argument
|
500
504
|
end
|
501
505
|
|
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"
|