open_api_import 0.10.9 → 0.11.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/lib/open_api_import/filter.rb +28 -0
- data/lib/open_api_import/get_data_all_of_bodies.rb +22 -0
- data/lib/open_api_import/get_examples.rb +88 -0
- data/lib/open_api_import/get_patterns.rb +67 -0
- data/lib/open_api_import/get_required_data.rb +30 -0
- data/lib/open_api_import/get_response_examples.rb +104 -0
- data/lib/open_api_import/open_api_import.rb +693 -0
- data/lib/open_api_import/pretty_hash_symbolized.rb +18 -0
- data/lib/open_api_import.rb +10 -1024
- metadata +36 -14
@@ -0,0 +1,693 @@
|
|
1
|
+
class OpenApiImport
|
2
|
+
##############################################################################################
|
3
|
+
# Import a Swagger or Open API file and create a Ruby Request Hash file including all requests and responses.
|
4
|
+
# The http methods that will be treated are: 'get','post','put','delete', 'patch'.
|
5
|
+
# @param swagger_file [String]. Path and file name. Could be absolute or relative to project root folder.
|
6
|
+
# @param include_responses [Boolean]. (default: true) if you want to add the examples of responses in the resultant file.
|
7
|
+
# @param mock_response [Boolean]. (default:false) Add the first response on the request as mock_response to be used.
|
8
|
+
# In case using nice_http gem: if NiceHttp.use_mocks = true will use it instead of getting the real response from the WS.
|
9
|
+
# @param create_method_name [Symbol]. (:path, :operation_id, :operationId) (default: operation_id). How the name of the methods will be generated.
|
10
|
+
# path: it will be used the path and http method, for example for a GET on path: /users/list, the method name will be get_users_list
|
11
|
+
# operation_id: it will be used the operationId field but using the snake_case version, for example for listUsers: list_users
|
12
|
+
# operationId: it will be used the operationId field like it is, for example: listUsers
|
13
|
+
# @param name_for_module [Symbol]. (:path, :path_file, :fixed, :tags, :tags_file) (default: :path). How the module names will be created.
|
14
|
+
# @param create_constants [Boolean]. (default: false) For required arguments, it will create keyword arguments assigning by default a constant.
|
15
|
+
# @param silent [Boolean]. (default: false) It will display only errors.
|
16
|
+
# path: It will be used the first folder of the path to create the module name, for example the path /users/list will be in the module Users and all the requests from all modules in the same file.
|
17
|
+
# path_file: It will be used the first folder of the path to create the module name, for example the path /users/list will be in the module Users and each module will be in a new requests file.
|
18
|
+
# tags: It will be used the tags key to create the module name, for example the tags: [users,list] will create the module UsersList and all the requests from all modules in the same file.
|
19
|
+
# tags_file: It will be used the tags key to create the module name, for example the tags: [users,list] will create the module UsersList and and each module will be in a new requests file.
|
20
|
+
# fixed: all the requests will be under the module Requests
|
21
|
+
##############################################################################################
|
22
|
+
def self.from(swagger_file, create_method_name: :operation_id, include_responses: true, mock_response: false, name_for_module: :path, silent: false, create_constants: false)
|
23
|
+
begin
|
24
|
+
f = File.new("#{swagger_file}_open_api_import.log", "w")
|
25
|
+
f.sync = true
|
26
|
+
@logger = Logger.new f
|
27
|
+
puts "Logs file: #{swagger_file}_open_api_import.log" unless silent
|
28
|
+
rescue StandardError => e
|
29
|
+
warn "Not possible to create the Logger file"
|
30
|
+
warn e
|
31
|
+
@logger = Logger.new nil
|
32
|
+
end
|
33
|
+
|
34
|
+
begin
|
35
|
+
@logger.info "swagger_file: #{swagger_file}, include_responses: #{include_responses}, mock_response: #{mock_response}\n"
|
36
|
+
@logger.info "create_method_name: #{create_method_name}, name_for_module: #{name_for_module}\n"
|
37
|
+
|
38
|
+
file_to_convert = if swagger_file["./"].nil?
|
39
|
+
swagger_file
|
40
|
+
else
|
41
|
+
Dir.pwd.to_s + "/" + swagger_file.gsub("./", "")
|
42
|
+
end
|
43
|
+
unless File.exist?(file_to_convert)
|
44
|
+
raise "The file #{file_to_convert} doesn't exist"
|
45
|
+
end
|
46
|
+
|
47
|
+
file_errors = file_to_convert + ".errors.log"
|
48
|
+
File.delete(file_errors) if File.exist?(file_errors)
|
49
|
+
import_errors = ""
|
50
|
+
required_constants = []
|
51
|
+
|
52
|
+
begin
|
53
|
+
definition = OasParser::Definition.resolve(swagger_file)
|
54
|
+
rescue Exception => stack
|
55
|
+
message = "There was a problem parsing the Open Api document using the oas_parser gem. The execution was aborted.\n"
|
56
|
+
message += "Visit the github for oas_parser gem for bugs and more info: https://github.com/Nexmo/oas_parser\n"
|
57
|
+
message += "Error: #{stack.message}"
|
58
|
+
puts message
|
59
|
+
@logger.fatal message
|
60
|
+
@logger.fatal stack.backtrace
|
61
|
+
exit!
|
62
|
+
end
|
63
|
+
|
64
|
+
raw = definition.raw.deep_symbolize_keys
|
65
|
+
|
66
|
+
if raw.key?(:openapi) && (raw[:openapi].to_f > 0)
|
67
|
+
raw[:swagger] = raw[:openapi]
|
68
|
+
end
|
69
|
+
if raw[:swagger].to_f < 2.0
|
70
|
+
raise "Unsupported Swagger version. Only versions >= 2.0 are valid."
|
71
|
+
end
|
72
|
+
|
73
|
+
base_host = ""
|
74
|
+
base_path = ""
|
75
|
+
|
76
|
+
base_host = raw[:host] if raw.key?(:host)
|
77
|
+
base_path = raw[:basePath] if raw.key?(:basePath)
|
78
|
+
module_name = raw[:info][:title].camel_case
|
79
|
+
module_version = "V#{raw[:info][:version].to_s.snake_case}"
|
80
|
+
|
81
|
+
output = []
|
82
|
+
output_header = []
|
83
|
+
output_header << "#" * 50
|
84
|
+
output_header << "# #{raw[:info][:title]}"
|
85
|
+
output_header << "# version: #{raw[:info][:version]}"
|
86
|
+
output_header << "# description: "
|
87
|
+
raw[:info][:description].to_s.split("\n").each do |d|
|
88
|
+
output_header << "# #{d}" unless d == ""
|
89
|
+
end
|
90
|
+
output_header << "#" * 50
|
91
|
+
|
92
|
+
output_header << "module Swagger"
|
93
|
+
output_header << "module #{module_name}"
|
94
|
+
output_header << "module #{module_version}"
|
95
|
+
output_header << "module Requests" if name_for_module == :fixed
|
96
|
+
|
97
|
+
files = {}
|
98
|
+
|
99
|
+
module_requests = ""
|
100
|
+
|
101
|
+
definition.paths.each do |path|
|
102
|
+
raw = path.raw.deep_symbolize_keys
|
103
|
+
|
104
|
+
if raw.key?(:parameters)
|
105
|
+
raw.each do |met, cont|
|
106
|
+
if met != :parameters
|
107
|
+
if raw[met].key?(:parameters)
|
108
|
+
#in case parameters for all methods in path is present
|
109
|
+
raw[met][:parameters] = raw[met][:parameters] + raw[:parameters]
|
110
|
+
else
|
111
|
+
raw[met][:parameters] = raw[:parameters]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
raw.delete(:parameters)
|
116
|
+
end
|
117
|
+
|
118
|
+
raw.each do |met, cont|
|
119
|
+
if %w[get post put delete patch].include?(met.to_s.downcase)
|
120
|
+
params = []
|
121
|
+
params_path = []
|
122
|
+
params_query = []
|
123
|
+
params_required = []
|
124
|
+
params_data = []
|
125
|
+
description_parameters = []
|
126
|
+
data_form = []
|
127
|
+
data_required = []
|
128
|
+
#todo: add nested one.true.three to data_read_only
|
129
|
+
data_read_only = []
|
130
|
+
data_default = []
|
131
|
+
data_examples = []
|
132
|
+
data_pattern = []
|
133
|
+
responses = []
|
134
|
+
|
135
|
+
# for the case operationId is missing
|
136
|
+
cont[:operationId] = "undefined" unless cont.key?(:operationId)
|
137
|
+
|
138
|
+
if create_method_name == :path
|
139
|
+
method_name = (met.to_s + "_" + path.path.to_s).snake_case
|
140
|
+
method_name.chop! if method_name[-1] == "_"
|
141
|
+
elsif create_method_name == :operation_id
|
142
|
+
if (name_for_module == :tags or name_for_module == :tags_file) and cont.key?(:tags) and cont[:tags].is_a?(Array) and cont[:tags].size > 0
|
143
|
+
metnametmp = cont[:operationId].gsub(/^#{cont[:tags].join}[\s_]*/, "")
|
144
|
+
cont[:tags].join.split(" ").each do |tag|
|
145
|
+
metnametmp.gsub!(/^#{tag}[\s_]*/i, "")
|
146
|
+
end
|
147
|
+
metnametmp = met if metnametmp == ""
|
148
|
+
else
|
149
|
+
metnametmp = cont[:operationId]
|
150
|
+
end
|
151
|
+
method_name = metnametmp.to_s.snake_case
|
152
|
+
else
|
153
|
+
if (name_for_module == :tags or name_for_module == :tags_file) and cont.key?(:tags) and cont[:tags].is_a?(Array) and cont[:tags].size > 0
|
154
|
+
method_name = cont[:operationId].gsub(/^#{cont[:tags].join}[\s_]*/, "")
|
155
|
+
cont[:tags].join.split(" ").each do |tag|
|
156
|
+
method_name.gsub!(/^#{tag}[\s_]*/i, "")
|
157
|
+
end
|
158
|
+
method_name = met if method_name == ""
|
159
|
+
else
|
160
|
+
method_name = cont[:operationId]
|
161
|
+
end
|
162
|
+
end
|
163
|
+
path_txt = path.path.dup.to_s
|
164
|
+
if [:path, :path_file, :tags, :tags_file].include?(name_for_module)
|
165
|
+
old_module_requests = module_requests
|
166
|
+
if [:path, :path_file].include?(name_for_module)
|
167
|
+
# to remove version from path fex: /v1/Customer
|
168
|
+
path_requests = path_txt.gsub(/^\/v[\d\.]*\//i, "")
|
169
|
+
# to remove version from path fex: /1.0/Customer
|
170
|
+
path_requests = path_requests.gsub(/^\/[\d\.]*\//i, "")
|
171
|
+
if (path_requests == path_txt) && (path_txt.scan("/").size == 1)
|
172
|
+
# no folder in path
|
173
|
+
module_requests = "Root"
|
174
|
+
else
|
175
|
+
res_path = path_requests.scan(/(\w+)/)
|
176
|
+
module_requests = res_path[0][0].camel_case
|
177
|
+
end
|
178
|
+
else
|
179
|
+
if cont.key?(:tags) and cont[:tags].is_a?(Array) and cont[:tags].size > 0
|
180
|
+
module_requests = cont[:tags].join(" ").camel_case
|
181
|
+
else
|
182
|
+
module_requests = "Undefined"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# to remove from method_name: v1_list_regions and add it to module
|
187
|
+
if /^(?<vers>v\d+)/i =~ method_name
|
188
|
+
method_name.gsub!(/^#{vers}_?/, "")
|
189
|
+
module_requests = (vers.capitalize + module_requests).camel_case unless module_requests.start_with?(vers)
|
190
|
+
end
|
191
|
+
|
192
|
+
if old_module_requests != module_requests
|
193
|
+
output << "end" unless old_module_requests == "" or name_for_module == :path_file or name_for_module == :tags_file
|
194
|
+
if name_for_module == :path or name_for_module == :tags
|
195
|
+
# to add the end for the previous module unless is the first one
|
196
|
+
output << "module #{module_requests}"
|
197
|
+
else #:path_file, :tags_file
|
198
|
+
if old_module_requests != ""
|
199
|
+
unless files.key?(old_module_requests)
|
200
|
+
files[old_module_requests] = Array.new
|
201
|
+
end
|
202
|
+
files[old_module_requests].concat(output)
|
203
|
+
output = Array.new
|
204
|
+
end
|
205
|
+
output << "module #{module_requests}" unless files.key?(module_requests) # don't add in case already existed
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
output << ""
|
211
|
+
output << "# operationId: #{cont[:operationId]}, method: #{met}"
|
212
|
+
output << "# summary: #{cont[:summary]}"
|
213
|
+
if !cont[:description].to_s.split("\n").empty?
|
214
|
+
output << "# description: "
|
215
|
+
cont[:description].to_s.split("\n").each do |d|
|
216
|
+
output << "# #{d}" unless d == ""
|
217
|
+
end
|
218
|
+
else
|
219
|
+
output << "# description: #{cont[:description]}"
|
220
|
+
end
|
221
|
+
|
222
|
+
mock_example = []
|
223
|
+
|
224
|
+
if include_responses && cont.key?(:responses) && cont[:responses].is_a?(Hash)
|
225
|
+
cont[:responses].each do |k, v|
|
226
|
+
response_example = []
|
227
|
+
response_example = get_response_examples(v)
|
228
|
+
|
229
|
+
data_pattern += get_patterns("", v[:schema]) if v.key?(:schema)
|
230
|
+
data_pattern.uniq!
|
231
|
+
v[:description] = v[:description].to_s.gsub("'", %q(\\\'))
|
232
|
+
if !response_example.empty?
|
233
|
+
responses << "'#{k}': { "
|
234
|
+
responses << "message: '#{v[:description]}', "
|
235
|
+
responses << "data: "
|
236
|
+
responses << response_example
|
237
|
+
responses << "},"
|
238
|
+
if mock_response and mock_example.size == 0
|
239
|
+
mock_example << "code: '#{k}',"
|
240
|
+
mock_example << "message: '#{v[:description]}',"
|
241
|
+
mock_example << "data: "
|
242
|
+
mock_example << response_example
|
243
|
+
end
|
244
|
+
else
|
245
|
+
responses << "'#{k}': { message: '#{v[:description]}'}, "
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
# todo: for open api 3.0 add the new Link feature: https://swagger.io/docs/specification/links/
|
250
|
+
# todo: for open api 3.0 is not getting the required params in all cases
|
251
|
+
|
252
|
+
# for the case open api 3 with cont.requestBody.content.'applicatin/json'.schema
|
253
|
+
# example: petstore-expanded.yaml operationId=addPet
|
254
|
+
if cont.key?(:requestBody) and cont[:requestBody].key?(:content) and
|
255
|
+
cont[:requestBody][:content].key?(:'application/json') and cont[:requestBody][:content][:'application/json'].key?(:schema)
|
256
|
+
cont[:parameters] = [] unless cont.key?(:parameters)
|
257
|
+
cont[:parameters] << { in: "body", schema: cont[:requestBody][:content][:'application/json'][:schema] }
|
258
|
+
end
|
259
|
+
|
260
|
+
data_examples_all_of = false
|
261
|
+
if cont.key?(:parameters) && cont[:parameters].is_a?(Array)
|
262
|
+
cont[:parameters].each do |p|
|
263
|
+
if p.keys.include?(:schema) and p[:schema].include?(:type)
|
264
|
+
type = p[:schema][:type]
|
265
|
+
elsif p.keys.include?(:type)
|
266
|
+
type = p[:type]
|
267
|
+
else
|
268
|
+
type = ""
|
269
|
+
end
|
270
|
+
|
271
|
+
if p[:in] == "path"
|
272
|
+
if create_method_name == :operationId
|
273
|
+
param_name = p[:name]
|
274
|
+
path_txt.gsub!("{#{param_name}}", "\#{#{param_name}}")
|
275
|
+
else
|
276
|
+
param_name = p[:name].to_s.snake_case
|
277
|
+
path_txt.gsub!("{#{p[:name]}}", "\#{#{param_name}}")
|
278
|
+
end
|
279
|
+
unless params_path.include?(param_name)
|
280
|
+
if create_constants
|
281
|
+
params_path << "#{param_name}: #{param_name.upcase}"
|
282
|
+
required_constants << param_name.upcase
|
283
|
+
else
|
284
|
+
params_path << param_name
|
285
|
+
end
|
286
|
+
#params_required << param_name if p[:required].to_s=="true"
|
287
|
+
description_parameters << "# #{p[:name]}: (#{type}) #{"(required)" if p[:required].to_s == "true"} #{p[:description].split("\n").join("\n#\t\t\t")}"
|
288
|
+
end
|
289
|
+
elsif p[:in] == "query"
|
290
|
+
params_query << p[:name]
|
291
|
+
params_required << p[:name] if p[:required].to_s == "true"
|
292
|
+
description_parameters << "# #{p[:name]}: (#{type}) #{"(required)" if p[:required].to_s == "true"} #{p[:description].split("\n").join("\n#\t\t\t")}"
|
293
|
+
elsif p[:in] == "formData" or p[:in] == "formdata"
|
294
|
+
#todo: take in consideration: default, required
|
295
|
+
#todo: see if we should add the required as params to the method and not required as options
|
296
|
+
#todo: set on data the required fields with the values from args
|
297
|
+
|
298
|
+
description_parameters << "# #{p[:name]}: (#{p[:type]}) #{p[:description].split("\n").join("\n#\t\t\t")}"
|
299
|
+
|
300
|
+
case p[:type]
|
301
|
+
when /^string$/i
|
302
|
+
data_form << "#{p[:name]}: ''"
|
303
|
+
when /^boolean$/i
|
304
|
+
data_form << "#{p[:name]}: true"
|
305
|
+
when /^number$/i
|
306
|
+
data_form << "#{p[:name]}: 0"
|
307
|
+
when /^integer$/i
|
308
|
+
data_form << "#{p[:name]}: 0"
|
309
|
+
else
|
310
|
+
puts "! on formData not supported type #{p[:type]}"
|
311
|
+
end
|
312
|
+
elsif p[:in] == "body"
|
313
|
+
if p.keys.include?(:schema)
|
314
|
+
if p[:schema].key?(:oneOf)
|
315
|
+
bodies = p[:schema][:oneOf]
|
316
|
+
elsif p[:schema].key?(:anyOf)
|
317
|
+
bodies = p[:schema][:anyOf]
|
318
|
+
elsif p[:schema].key?(:allOf)
|
319
|
+
data_examples_all_of, bodies = get_data_all_of_bodies(p)
|
320
|
+
bodies.unshift(p[:schema]) if p[:schema].key?(:required) or p.key?(:required) #todo: check if this 'if' is necessary
|
321
|
+
data_examples_all_of = true # because we are on data and allOf already
|
322
|
+
else
|
323
|
+
bodies = [p[:schema]]
|
324
|
+
end
|
325
|
+
|
326
|
+
params_data = []
|
327
|
+
|
328
|
+
bodies.each do |body|
|
329
|
+
data_required += get_required_data(body)
|
330
|
+
all_properties = []
|
331
|
+
all_properties << body[:properties] if body.keys.include?(:properties) and body[:properties].size > 0
|
332
|
+
if body.key?(:allOf)
|
333
|
+
body[:allOf].each do |item|
|
334
|
+
all_properties << item[:properties] if item.key?(:properties)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
all_properties.each do |props|
|
339
|
+
props.each { |dpk, dpv|
|
340
|
+
if dpv.keys.include?(:example)
|
341
|
+
if dpv[:example].is_a?(Array) and dpv.type != "array"
|
342
|
+
valv = dpv[:example][0]
|
343
|
+
else
|
344
|
+
valv = dpv[:example].to_s
|
345
|
+
end
|
346
|
+
else
|
347
|
+
if dpv.type == "object"
|
348
|
+
if dpv.key?(:properties)
|
349
|
+
valv = get_examples(dpv[:properties], :key_value, true).join("\n")
|
350
|
+
else
|
351
|
+
valv = "{}"
|
352
|
+
end
|
353
|
+
elsif dpv.type == "array"
|
354
|
+
if dpv.key?(:items)
|
355
|
+
valv = get_examples({ dpk => dpv }, :only_value)
|
356
|
+
valv = valv.join("\n")
|
357
|
+
else
|
358
|
+
valv = "[]"
|
359
|
+
end
|
360
|
+
else
|
361
|
+
valv = ""
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
if dpv.keys.include?(:description)
|
366
|
+
description_parameters << "# #{dpk}: (#{dpv[:type]}) #{dpv[:description].split("\n").join("\n#\t\t\t")}"
|
367
|
+
end
|
368
|
+
|
369
|
+
data_pattern += get_patterns(dpk, dpv)
|
370
|
+
data_pattern.uniq!
|
371
|
+
dpkeys = []
|
372
|
+
data_pattern.reject! do |dp|
|
373
|
+
dpkey = dp.scan(/^'[\w\.]+'/)
|
374
|
+
|
375
|
+
if dpkeys.include?(dpkey)
|
376
|
+
true
|
377
|
+
else
|
378
|
+
dpkeys << dpkey
|
379
|
+
false
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
if dpv.keys.include?(:readOnly) and dpv[:readOnly] == true
|
384
|
+
data_read_only << dpk
|
385
|
+
end
|
386
|
+
if dpv.keys.include?(:default)
|
387
|
+
if dpv[:default].nil?
|
388
|
+
data_default << "#{dpk}: nil"
|
389
|
+
elsif dpv.type != "string"
|
390
|
+
data_default << "#{dpk}: #{dpv[:default]}"
|
391
|
+
else
|
392
|
+
data_default << "#{dpk}: '#{dpv[:default]}'"
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
#todo: consider check default and insert it
|
397
|
+
#todo: remove array from here and add the option to get_examples for the case thisisthekey: ['xxxx']
|
398
|
+
if dpv.key?(:type) and dpv[:type] != "array"
|
399
|
+
params_data << get_examples({ dpk => dpv }, :only_value, true).join
|
400
|
+
params_data[-1].chop!.chop! if params_data[-1].to_s[-2..-1] == ", "
|
401
|
+
params_data.pop if params_data[-1].match?(/^\s*$/im)
|
402
|
+
else
|
403
|
+
if valv.to_s == ""
|
404
|
+
valv = '""'
|
405
|
+
elsif valv.include?('"')
|
406
|
+
valv.gsub!('"', "'")
|
407
|
+
end
|
408
|
+
params_data << "#{dpk}: #{valv}"
|
409
|
+
end
|
410
|
+
}
|
411
|
+
if params_data.size > 0
|
412
|
+
if data_examples_all_of == true and data_examples.size > 0
|
413
|
+
data_examples[0] += params_data
|
414
|
+
else
|
415
|
+
data_examples << params_data
|
416
|
+
end
|
417
|
+
params_data = []
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
unless data_required.empty?
|
423
|
+
data_required.uniq!
|
424
|
+
output << "# required data: #{data_required.inspect}"
|
425
|
+
end
|
426
|
+
end
|
427
|
+
elsif p[:in] == "header"
|
428
|
+
#todo: see how we can treat those cases
|
429
|
+
else
|
430
|
+
puts "! not imported data with :in:#{p[:in]} => #{p.inspect}"
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
params = params_path
|
435
|
+
|
436
|
+
unless params_query.empty?
|
437
|
+
path_txt += "?"
|
438
|
+
params_required.each do |pr|
|
439
|
+
if create_constants
|
440
|
+
if params_query.include?(pr)
|
441
|
+
if create_method_name == :operationId
|
442
|
+
path_txt += "#{pr}=\#{#{pr}}&"
|
443
|
+
params << "#{pr}: #{pr.upcase}"
|
444
|
+
required_constants << pr.upcase
|
445
|
+
else
|
446
|
+
path_txt += "#{pr}=\#{#{pr.to_s.snake_case}}&"
|
447
|
+
params << "#{pr.to_s.snake_case}: #{pr.to_s.snake_case.upcase}"
|
448
|
+
required_constants << pr.to_s.snake_case.upcase
|
449
|
+
end
|
450
|
+
end
|
451
|
+
else
|
452
|
+
if params_query.include?(pr)
|
453
|
+
if create_method_name == :operationId
|
454
|
+
path_txt += "#{pr}=\#{#{pr}}&"
|
455
|
+
params << "#{pr}"
|
456
|
+
else
|
457
|
+
path_txt += "#{pr}=\#{#{pr.to_s.snake_case}}&"
|
458
|
+
params << "#{pr.to_s.snake_case}"
|
459
|
+
end
|
460
|
+
end
|
461
|
+
end
|
462
|
+
end
|
463
|
+
params_query.each do |pq|
|
464
|
+
unless params_required.include?(pq)
|
465
|
+
if create_method_name == :operationId
|
466
|
+
path_txt += "#{pq}=\#{#{pq}}&"
|
467
|
+
params << "#{pq}: ''"
|
468
|
+
else
|
469
|
+
path_txt += "#{pq}=\#{#{pq.to_s.snake_case}}&"
|
470
|
+
params << "#{pq.to_s.snake_case}: ''"
|
471
|
+
end
|
472
|
+
end
|
473
|
+
end
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
if description_parameters.size > 0
|
478
|
+
output << "# parameters description: "
|
479
|
+
output << description_parameters.uniq
|
480
|
+
end
|
481
|
+
|
482
|
+
#for the case we still have some parameters on path that were not in 'parameters'
|
483
|
+
if path_txt.scan(/[^#]{\w+}/).size > 0
|
484
|
+
paramst = []
|
485
|
+
prms = path_txt.scan(/[^#]{(\w+)}/)
|
486
|
+
prms.each do |p|
|
487
|
+
#if create_constants
|
488
|
+
# paramst<<"#{p[0].to_s.snake_case}: #{p[0].to_s.snake_case.upcase}"
|
489
|
+
# required_constants << p[0].to_s.snake_case.upcase
|
490
|
+
#else
|
491
|
+
paramst << p[0].to_s.snake_case
|
492
|
+
#end
|
493
|
+
path_txt.gsub!("{#{p[0]}}", "\#{#{p[0].to_s.snake_case}}")
|
494
|
+
end
|
495
|
+
paramst.concat params
|
496
|
+
params = paramst
|
497
|
+
end
|
498
|
+
params.uniq!
|
499
|
+
output << "def self.#{method_name} (#{params.join(", ")})"
|
500
|
+
|
501
|
+
output << "{"
|
502
|
+
|
503
|
+
output << "name: \"#{module_requests}.#{method_name}\","
|
504
|
+
|
505
|
+
output << "path: \"#{base_path}#{path_txt}\","
|
506
|
+
|
507
|
+
output << "method: :#{met}," if met.to_s != ""
|
508
|
+
|
509
|
+
unless data_required.empty?
|
510
|
+
output << "data_required: ["
|
511
|
+
output << ":'#{data_required.uniq.join("', :'")}'"
|
512
|
+
output << "],"
|
513
|
+
end
|
514
|
+
unless data_read_only.empty?
|
515
|
+
output << "data_read_only: ["
|
516
|
+
output << ":'#{data_read_only.uniq.join("', :'")}'"
|
517
|
+
output << "],"
|
518
|
+
end
|
519
|
+
unless data_default.empty?
|
520
|
+
output << "data_default: {"
|
521
|
+
data_default.uniq!
|
522
|
+
output << data_default.join(", \n")
|
523
|
+
output << "},"
|
524
|
+
end
|
525
|
+
|
526
|
+
unless data_pattern.empty?
|
527
|
+
output << "data_pattern: {"
|
528
|
+
output << data_pattern.uniq.join(", \n")
|
529
|
+
output << "},"
|
530
|
+
end
|
531
|
+
|
532
|
+
unless data_form.empty?
|
533
|
+
data_examples << data_form
|
534
|
+
end
|
535
|
+
|
536
|
+
unless data_examples.empty?
|
537
|
+
unless data_required.empty?
|
538
|
+
reqdata = []
|
539
|
+
begin
|
540
|
+
data_examples[0].uniq!
|
541
|
+
data_ex = eval("{#{data_examples[0].join(", ")}}")
|
542
|
+
rescue
|
543
|
+
data_ex = {}
|
544
|
+
end
|
545
|
+
if (data_required.grep(/\./)).empty?
|
546
|
+
reqdata = filter(data_ex, data_required) #not nested
|
547
|
+
else
|
548
|
+
reqdata = filter(data_ex, data_required, true) #nested
|
549
|
+
end
|
550
|
+
unless reqdata.empty?
|
551
|
+
phsd = pretty_hash_symbolized(reqdata)
|
552
|
+
phsd[0] = "data: {"
|
553
|
+
output += phsd
|
554
|
+
end
|
555
|
+
end
|
556
|
+
unless data_read_only.empty? or !data_required.empty?
|
557
|
+
reqdata = []
|
558
|
+
#remove read only fields from :data
|
559
|
+
data_examples[0].each do |edata|
|
560
|
+
read_only = false
|
561
|
+
data_read_only.each do |rdata|
|
562
|
+
if edata.scan(/^#{rdata}:/).size > 0
|
563
|
+
read_only = true
|
564
|
+
break
|
565
|
+
elsif edata.scan(/:/).size == 0
|
566
|
+
break
|
567
|
+
end
|
568
|
+
end
|
569
|
+
reqdata << edata unless read_only
|
570
|
+
end
|
571
|
+
unless reqdata.empty?
|
572
|
+
output << "data: {"
|
573
|
+
output << reqdata.join(", \n")
|
574
|
+
output << "},"
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
output << "data_examples: ["
|
579
|
+
data_examples.each do |data|
|
580
|
+
output << "{"
|
581
|
+
data.uniq!
|
582
|
+
output << data.join(", \n")
|
583
|
+
output << "}, "
|
584
|
+
end
|
585
|
+
output << "],"
|
586
|
+
end
|
587
|
+
|
588
|
+
unless mock_example.empty?
|
589
|
+
output << "mock_response: {"
|
590
|
+
output << mock_example
|
591
|
+
output << "},"
|
592
|
+
end
|
593
|
+
|
594
|
+
unless responses.empty?
|
595
|
+
output << "responses: {"
|
596
|
+
output << responses
|
597
|
+
output << "},"
|
598
|
+
end
|
599
|
+
|
600
|
+
output << "}"
|
601
|
+
output << "end"
|
602
|
+
else
|
603
|
+
@logger.warn "Not imported method: #{met} for path: #{path.path} since it is not supported by OpenApiImport"
|
604
|
+
end
|
605
|
+
end
|
606
|
+
end
|
607
|
+
output_footer = []
|
608
|
+
|
609
|
+
output_footer << "end" unless (module_requests == "") && ([:path, :path_file, :tags, :tags_file].include?(name_for_module))
|
610
|
+
output_footer << "end" << "end" << "end"
|
611
|
+
|
612
|
+
if files.size == 0
|
613
|
+
output = output_header + output + output_footer
|
614
|
+
output_txt = output.join("\n")
|
615
|
+
requests_file_path = file_to_convert + ".rb"
|
616
|
+
File.open(requests_file_path, "w") { |file| file.write(output_txt) }
|
617
|
+
res_rufo = `rufo #{requests_file_path}`
|
618
|
+
message = "** Requests file: #{swagger_file}.rb that contains the code of the requests after importing the Swagger file"
|
619
|
+
puts message unless silent
|
620
|
+
@logger.info message
|
621
|
+
@logger.error " Error formating with rufo" unless res_rufo.to_s.match?(/\AFormat:.+$\s*\z/)
|
622
|
+
@logger.error " Syntax Error: #{`ruby -c #{requests_file_path}`}" unless `ruby -c #{requests_file_path}`.include?("Syntax OK")
|
623
|
+
else
|
624
|
+
unless files.key?(module_requests)
|
625
|
+
files[module_requests] = Array.new
|
626
|
+
end
|
627
|
+
files[module_requests].concat(output) #for the last one
|
628
|
+
|
629
|
+
requires_txt = ""
|
630
|
+
message = "** Generated files that contain the code of the requests after importing the Swagger file: "
|
631
|
+
puts message unless silent
|
632
|
+
@logger.info message
|
633
|
+
files.each do |mod, out_mod|
|
634
|
+
output = output_header + out_mod + output_footer
|
635
|
+
output_txt = output.join("\n")
|
636
|
+
requests_file_path = file_to_convert + "_" + mod + ".rb"
|
637
|
+
requires_txt += "require_relative '#{File.basename(swagger_file)}_#{mod}'\n"
|
638
|
+
File.open(requests_file_path, "w") { |file| file.write(output_txt) }
|
639
|
+
res_rufo = `rufo #{requests_file_path}`
|
640
|
+
message = " - #{requests_file_path}"
|
641
|
+
puts message unless silent
|
642
|
+
@logger.info message
|
643
|
+
@logger.error " Error formating with rufo" unless res_rufo.to_s.match?(/\AFormat:.+$\s*\z/)
|
644
|
+
@logger.error " Syntax Error: #{`ruby -c #{requests_file_path}`}" unless `ruby -c #{requests_file_path}`.include?("Syntax OK")
|
645
|
+
end
|
646
|
+
|
647
|
+
requests_file_path = file_to_convert + ".rb"
|
648
|
+
if required_constants.size > 0
|
649
|
+
rconsts = "# Required constants\n"
|
650
|
+
required_constants.uniq!
|
651
|
+
required_constants.each do |rq|
|
652
|
+
rconsts += "#{rq} ||= ENV['#{rq}'] ||=''\n"
|
653
|
+
end
|
654
|
+
rconsts += "\n\n"
|
655
|
+
else
|
656
|
+
rconsts = ""
|
657
|
+
end
|
658
|
+
|
659
|
+
File.open(requests_file_path, "w") { |file| file.write(rconsts + requires_txt) }
|
660
|
+
res_rufo = `rufo #{requests_file_path}`
|
661
|
+
message = "** File that contains all the requires for all Request files: \n"
|
662
|
+
message += " - #{requests_file_path} "
|
663
|
+
puts message unless silent
|
664
|
+
@logger.info message
|
665
|
+
@logger.error " Error formating with rufo" unless res_rufo.to_s.match?(/\AFormat:.+$\s*\z/)
|
666
|
+
@logger.error " Syntax Error: #{`ruby -c #{requests_file_path}`}" unless `ruby -c #{requests_file_path}`.include?("Syntax OK")
|
667
|
+
end
|
668
|
+
|
669
|
+
begin
|
670
|
+
res = eval(output_txt)
|
671
|
+
rescue Exception => stack
|
672
|
+
import_errors += "\n\nResult evaluating the ruby file generated: \n" + stack.to_s
|
673
|
+
end
|
674
|
+
|
675
|
+
if import_errors.to_s != ""
|
676
|
+
File.open(file_errors, "w") { |file| file.write(import_errors) }
|
677
|
+
message = "* It seems there was a problem importing the Swagger file #{file_to_convert}\n"
|
678
|
+
message += "* Take a look at the detected errors at #{file_errors}\n"
|
679
|
+
warn message
|
680
|
+
@logger.fatal message
|
681
|
+
return false
|
682
|
+
else
|
683
|
+
return true
|
684
|
+
end
|
685
|
+
rescue StandardError => stack
|
686
|
+
puts stack.message
|
687
|
+
@logger.fatal stack.message
|
688
|
+
@logger.fatal stack.backtrace
|
689
|
+
puts stack.backtrace
|
690
|
+
end
|
691
|
+
end
|
692
|
+
end
|
693
|
+
|