open_api_import 0.10.11 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ff3ff403e355b1f422b8d005c1302c2c22f77507d2c1785fe5446050e044096
4
- data.tar.gz: 5f2c733cac57f1db5e88504e3aba1db7b61241378ecdb89d7ed68e1012e95012
3
+ metadata.gz: a1a667b9e2ed3c9f4edc515345bdc6d85929fa6274138b6201ed8c72de085174
4
+ data.tar.gz: 4824ac5351b6e45e9ac82ef3979e39c706a28134469de1dde945f88278728337
5
5
  SHA512:
6
- metadata.gz: 583ae4003d2bb422e87cd0502b4f0cd317ffbb0919c1113d44d8173546dee5afdb32a0e8b62b1bea89aa18a713c4b8fb2a6299a90ed2de233c9d1890aeffcdd5
7
- data.tar.gz: f392b2a77e39447efec45dca83a13deb22d2561e96432487a7bf25861b95d9e059006311fd316fa6e989de22b66c6d3c981e6d0c80b60cca9618b75364ded7f0
6
+ metadata.gz: 5795d34e5541ba890be3804f6d14fe13eec276f66e5dc5ab14430bd4eecda2ae633e2ae1fc50a1a7c60ba5d52d1627072770cce8c996f4e4a11503f8981ee79b
7
+ data.tar.gz: be67993cee72e6df7d7d81a4e572c0db3ed814c6c637fb5c57ac6a3e59dcfc98b7f3a1e5eeca856b8a9578c766c8396540fb2fe26b3340a931e8d7681fc72bdd
@@ -0,0 +1,28 @@
1
+ module LibOpenApiImport
2
+ #filter hash
3
+ def filter(hash, keys, nested = false)
4
+ result = {}
5
+ keys = [keys] unless keys.is_a?(Array)
6
+ if nested
7
+ result = hash.nice_filter(keys)
8
+ else
9
+ #to be backwards compatible
10
+ keys.each do |k|
11
+ if k.is_a?(Symbol) and hash.key?(k)
12
+ if hash[k].is_a?(Hash)
13
+ result[k] = {}
14
+ else
15
+ result[k] = hash[k]
16
+ end
17
+ elsif k.is_a?(Symbol) and k.to_s.include?(".") and hash.key?((k.to_s.scan(/(\w+)\./).join).to_sym) #nested 'uno.dos.tres
18
+ kn = k.to_s.split(".")
19
+ vn = kn[1].to_sym
20
+ result[kn.first.to_sym][vn] = filter(hash[kn.first.to_sym], vn).values[0]
21
+ elsif k.is_a?(Hash) and hash.key?(k.keys[0]) #nested {uno: {dos: :tres}}
22
+ result[k.keys[0]][k.values[0]] = filter(hash[k.keys[0]], k.values[0]).values[0]
23
+ end
24
+ end
25
+ end
26
+ return result
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ module LibOpenApiImport
2
+ private def get_data_all_of_bodies(p)
3
+ bodies = []
4
+ data_examples_all_of = false
5
+ if p.is_a?(Array)
6
+ q = p
7
+ elsif p.key?(:schema) and p[:schema].key?(:allOf)
8
+ q = p[:schema][:allOf]
9
+ else
10
+ q = [p]
11
+ end
12
+ q.each do |pt|
13
+ if pt.is_a?(Hash) and pt.key?(:allOf)
14
+ bodies += get_data_all_of_bodies(pt[:allOf])[1]
15
+ data_examples_all_of = true
16
+ else
17
+ bodies << pt
18
+ end
19
+ end
20
+ return data_examples_all_of, bodies
21
+ end
22
+ end
@@ -0,0 +1,88 @@
1
+ module LibOpenApiImport
2
+ # Retrieve the examples from the properties hash
3
+ private def get_examples(properties, type = :key_value, remove_readonly = false)
4
+ #todo: consider using this method also to get data examples
5
+ example = []
6
+ example << "{" unless properties.empty? or type == :only_value
7
+ properties.each do |prop, val|
8
+ unless remove_readonly and val.key?(:readOnly) and val[:readOnly] == true
9
+ if val.key?(:properties) and !val.key?(:example) and !val.key?(:type)
10
+ val[:type] = "object"
11
+ end
12
+ if val.key?(:items) and !val.key?(:example) and !val.key?(:type)
13
+ val[:type] = "array"
14
+ end
15
+ if val.key?(:example)
16
+ if val[:example].is_a?(Array) and val.key?(:type) and val[:type] == "string"
17
+ example << " #{prop.to_sym}: \"#{val[:example][0]}\", " # only the first example
18
+ else
19
+ if val[:example].is_a?(String)
20
+ val[:example].gsub!('"', "'")
21
+ example << " #{prop.to_sym}: \"#{val[:example]}\", "
22
+ elsif val[:example].is_a?(Time)
23
+ example << " #{prop.to_sym}: \"#{val[:example]}\", "
24
+ else
25
+ example << " #{prop.to_sym}: #{val[:example]}, "
26
+ end
27
+ end
28
+ elsif val.key?(:type)
29
+ format = val[:format]
30
+ format = val[:type] if format.to_s == ""
31
+ case val[:type].downcase
32
+ when "string"
33
+ example << " #{prop.to_sym}: \"#{format}\", "
34
+ when "integer", "number"
35
+ example << " #{prop.to_sym}: 0, "
36
+ when "boolean"
37
+ example << " #{prop.to_sym}: true, "
38
+ when "array"
39
+ if val.key?(:items) and val[:items].size == 1 and val[:items].is_a?(Hash) and val[:items].key?(:type)
40
+ val[:items][:enum] = [val[:items][:type]]
41
+ end
42
+
43
+ if val.key?(:items) and val[:items].key?(:enum)
44
+ #before we were getting in all these cases a random value from the enum, now we are getting the first position by default
45
+ #the reason is to avoid confusion later in case we want to compare two swaggers and verify the changes
46
+ if type == :only_value
47
+ if val[:items][:enum][0].is_a?(String)
48
+ example << " [\"" + val[:items][:enum][0] + "\"] "
49
+ else
50
+ example << " [" + val[:items][:enum][0] + "] "
51
+ end
52
+ else
53
+ if val[:items][:enum][0].is_a?(String)
54
+ example << " #{prop.to_sym}: [\"" + val[:items][:enum][0] + "\"], "
55
+ else
56
+ example << " #{prop.to_sym}: [" + val[:items][:enum][0] + "], "
57
+ end
58
+ end
59
+ else
60
+ #todo: differ between response examples and data examples
61
+ examplet = get_response_examples({ schema: val }, remove_readonly).join("\n")
62
+ examplet = '[]' if examplet.empty?
63
+ if type == :only_value
64
+ example << examplet
65
+ else
66
+ example << " #{prop.to_sym}: " + examplet + ", "
67
+ end
68
+
69
+ end
70
+ when "object"
71
+ #todo: differ between response examples and data examples
72
+ res_ex = get_response_examples({ schema: val }, remove_readonly)
73
+ if res_ex.size == 0
74
+ res_ex = "{ }"
75
+ else
76
+ res_ex = res_ex.join("\n")
77
+ end
78
+ example << " #{prop.to_sym}: " + res_ex + ", "
79
+ else
80
+ example << " #{prop.to_sym}: \"#{format}\", "
81
+ end
82
+ end
83
+ end
84
+ end
85
+ example << "}" unless properties.empty? or type == :only_value
86
+ example
87
+ end
88
+ end
@@ -0,0 +1,67 @@
1
+ module LibOpenApiImport
2
+ # Get patterns
3
+ private def get_patterns(dpk, dpv)
4
+ data_pattern = []
5
+ if dpv.keys.include?(:pattern)
6
+ #todo: control better the cases with back slashes
7
+ if dpv[:pattern].include?('\\\\/')
8
+ #for cases like this: ^[^\.\\/:*?"<>|][^\\/:*?"<>|]{0,13}[^\.\\/:*?"<>|]?$
9
+ data_pattern << "'#{dpk}': /#{dpv[:pattern].to_s.gsub('\/', "/")}/"
10
+ elsif dpv[:pattern].include?('\\x')
11
+ data_pattern << "'#{dpk}': /#{dpv[:pattern].to_s.gsub('\\x', '\\u')}/"
12
+ else
13
+ data_pattern << "'#{dpk}': /#{dpv[:pattern].to_s}/"
14
+ end
15
+ elsif dpv.key?(:minLength) and dpv.key?(:maxLength)
16
+ data_pattern << "'#{dpk}': :'#{dpv[:minLength]}-#{dpv[:maxLength]}:LN$'"
17
+ elsif dpv.key?(:minLength) and !dpv.key?(:maxLength)
18
+ data_pattern << "'#{dpk}': :'#{dpv[:minLength]}:LN$'"
19
+ elsif !dpv.key?(:minLength) and dpv.key?(:maxLength)
20
+ data_pattern << "'#{dpk}': :'0-#{dpv[:maxLength]}:LN$'"
21
+ elsif dpv.key?(:minimum) and dpv.key?(:maximum) and dpv[:type] == "string"
22
+ data_pattern << "'#{dpk}': :'#{dpv[:minimum]}-#{dpv[:maximum]}:LN$'"
23
+ elsif dpv.key?(:minimum) and dpv.key?(:maximum)
24
+ data_pattern << "'#{dpk}': #{dpv[:minimum]}..#{dpv[:maximum]}"
25
+ elsif dpv.key?(:minimum) and !dpv.key?(:maximum)
26
+ if RUBY_VERSION >= "2.6.0"
27
+ data_pattern << "'#{dpk}': #{dpv[:minimum]}.. "
28
+ else
29
+ data_pattern << "#'#{dpk}': #{dpv[:minimum]}.. # INFINITE only working on ruby>=2.6.0"
30
+ end
31
+ elsif !dpv.key?(:minimum) and dpv.key?(:maximum)
32
+ data_pattern << "'#{dpk}': 0..#{dpv[:maximum]}"
33
+ elsif dpv[:format] == "date-time"
34
+ data_pattern << "'#{dpk}': DateTime"
35
+ elsif dpv[:type] == "boolean"
36
+ data_pattern << "'#{dpk}': Boolean"
37
+ elsif dpv.key?(:enum)
38
+ data_pattern << "'#{dpk}': :'#{dpv[:enum].join("|")}'"
39
+ elsif dpv[:type] == "array" and dpv.key?(:items) and dpv[:items].is_a?(Hash) and dpv[:items].key?(:enum) and dpv[:items][:enum].is_a?(Array)
40
+ #{:title=>"Balala", :type=>"array", :items=>{:type=>"string", :enum=>["uno","dos"], :example=>"uno"}}
41
+ data_pattern << "'#{dpk}': [:'#{dpv[:items][:enum].join("|")}']"
42
+ elsif dpv[:type] == "array" and dpv.key?(:items) and dpv[:items].is_a?(Hash) and !dpv[:items].key?(:enum) and dpv[:items].key?(:properties)
43
+ #{:title=>"Balala", :type=>"array", :items=>{title: 'xxxx, properties: {server: {enum:['ibm','msa','pytan']}}}
44
+ dpv[:items][:properties].each do |dpkk, dpvv|
45
+ if dpk == ""
46
+ data_pattern += get_patterns("#{dpkk}", dpvv)
47
+ else
48
+ data_pattern += get_patterns("#{dpk}.#{dpkk}", dpvv)
49
+ end
50
+ end
51
+ elsif dpv[:type] == "array" and dpv.key?(:items) and dpv[:items].is_a?(Hash) and
52
+ !dpv[:items].key?(:enum) and !dpv[:items].key?(:properties) and dpv[:items].key?(:type)
53
+ #{:title=>"labels", :description=>"Labels specified for the file system", :type=>"array", :items=>{:type=>"string", :enum=>["string"]}}
54
+ data_pattern << "'#{dpk}': [ #{get_patterns("", dpv[:items]).join[4..-1]} ]"
55
+ elsif dpv[:type] == "object" and dpv.key?(:properties)
56
+ dpv[:properties].each do |dpkk, dpvv|
57
+ if dpk == ""
58
+ data_pattern += get_patterns("#{dpkk}", dpvv)
59
+ else
60
+ data_pattern += get_patterns("#{dpk}.#{dpkk}", dpvv)
61
+ end
62
+ end
63
+ end
64
+ data_pattern.uniq!
65
+ return data_pattern
66
+ end
67
+ end
@@ -0,0 +1,30 @@
1
+ module LibOpenApiImport
2
+ # Get required data
3
+ private def get_required_data(body)
4
+ data_required = []
5
+ if body.keys.include?(:required) and body[:required].size > 0
6
+ body[:required].each do |r|
7
+ data_required << r.to_sym
8
+ end
9
+ end
10
+ if body.key?(:allOf)
11
+ body[:allOf].each do |r|
12
+ if r.key?(:required)
13
+ r[:required].each do |r2|
14
+ data_required << r2.to_sym
15
+ end
16
+ end
17
+ end
18
+ end
19
+ data_required.each do |key|
20
+ if body.key?(:properties) and body[:properties][key].is_a?(Hash) and
21
+ body[:properties][key].key?(:required) and body[:properties][key][:required].size > 0
22
+ dr = get_required_data(body[:properties][key])
23
+ dr.each do |k|
24
+ data_required.push("#{key}.#{k}".to_sym)
25
+ end
26
+ end
27
+ end
28
+ return data_required
29
+ end
30
+ end
@@ -0,0 +1,104 @@
1
+ module LibOpenApiImport
2
+ # Retrieve the response examples from the hash
3
+ private def get_response_examples(v, remove_readonly = false)
4
+ # TODO: take in consideration the case allOf, oneOf... schema.items.allOf[0].properties schema.items.allOf[1].properties
5
+ # example on https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/yaml/petstore-expanded.yaml
6
+ v = v.dup
7
+ response_example = Array.new()
8
+ # for open api 3.0 with responses schema inside content
9
+ if v.key?(:content) && v[:content].is_a?(Hash) && v[:content].key?(:'application/json') &&
10
+ v[:content][:'application/json'].key?(:schema)
11
+ v = v[:content][:'application/json'].dup
12
+ end
13
+ if v.key?(:examples) && v[:examples].is_a?(Hash) && v[:examples].key?(:'application/json')
14
+ if v[:examples][:'application/json'].is_a?(String)
15
+ response_example << v[:examples][:'application/json']
16
+ elsif v[:examples][:'application/json'].is_a?(Hash)
17
+ exs = v[:examples][:'application/json'].to_s
18
+ exs.gsub!(/:(\w+)=>/, "\n\\1: ")
19
+ response_example << exs
20
+ elsif v[:examples][:'application/json'].is_a?(Array)
21
+ response_example << "["
22
+ v[:examples][:'application/json'].each do |ex|
23
+ exs = ex.to_s
24
+ if ex.is_a?(Hash)
25
+ exs.gsub!(/:(\w+)=>/, "\n\\1: ")
26
+ end
27
+ response_example << (exs + ", ")
28
+ end
29
+ response_example << "]"
30
+ end
31
+ # for open api 3.0. examples on reponses, for example: api-with-examples.yaml
32
+ elsif v.key?(:content) && v[:content].is_a?(Hash) && v[:content].key?(:'application/json') &&
33
+ v[:content][:'application/json'].key?(:examples)
34
+ v[:content][:'application/json'][:examples].each do |tk, tv|
35
+ #todo: for the moment we only take in consideration the first example of response.
36
+ # we need to decide how to manage to do it correctly
37
+ if tv.key?(:value)
38
+ tresp = tv[:value]
39
+ else
40
+ tresp = ""
41
+ end
42
+ if tresp.is_a?(String)
43
+ response_example << tresp
44
+ elsif tresp.is_a?(Hash)
45
+ exs = tresp.to_s
46
+ exs.gsub!(/:(\w+)=>/, "\n\\1: ")
47
+ response_example << exs
48
+ elsif tresp.is_a?(Array)
49
+ response_example << "["
50
+ tresp.each do |ex|
51
+ exs = ex.to_s
52
+ if ex.is_a?(Hash)
53
+ exs.gsub!(/:(\w+)=>/, "\n\\1: ")
54
+ end
55
+ response_example << (exs + ", ")
56
+ end
57
+ response_example << "]"
58
+ end
59
+ break #only the first one it is considered
60
+ end
61
+ elsif v.key?(:schema) && v[:schema].is_a?(Hash) &&
62
+ (v[:schema].key?(:properties) ||
63
+ (v[:schema].key?(:items) && v[:schema][:items].key?(:properties)) ||
64
+ (v[:schema].key?(:items) && v[:schema][:items].key?(:allOf)) ||
65
+ v[:schema].key?(:allOf))
66
+ properties = {}
67
+ if v[:schema].key?(:properties)
68
+ properties = v[:schema][:properties]
69
+ elsif v[:schema].key?(:allOf)
70
+ v[:schema][:allOf].each do |pr|
71
+ properties.merge!(pr[:properties]) if pr.key?(:properties)
72
+ end
73
+ elsif v[:schema][:items].key?(:properties)
74
+ properties = v[:schema][:items][:properties]
75
+ response_example << "["
76
+ elsif v[:schema][:items].key?(:allOf)
77
+ v[:schema][:items][:allOf].each do |pr|
78
+ properties.merge!(pr[:properties]) if pr.key?(:properties)
79
+ end
80
+ response_example << "["
81
+ end
82
+
83
+ response_example += get_examples(properties, :key_value, remove_readonly) unless properties.empty?
84
+
85
+ unless response_example.empty?
86
+ if v[:schema].key?(:properties) || v[:schema].key?(:allOf)
87
+ #
88
+ else # array, items
89
+ response_example << "]"
90
+ end
91
+ end
92
+ elsif v.key?(:schema) and v[:schema].key?(:items) and v[:schema][:items].key?(:type)
93
+ # for the case only type supplied but nothing else for the array
94
+ response_example << "[\"#{v[:schema][:items][:type]}\"]"
95
+ end
96
+ response_example.each do |rs|
97
+ #(@type Google) for the case in example the key is something like: @type:
98
+ if rs.match?(/^\s*@\w+:/)
99
+ rs.gsub!(/@(\w+):/, '\'@\1\':')
100
+ end
101
+ end
102
+ return response_example
103
+ end
104
+ end