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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e1707e266a2104ec005d5c7d5081ffd51c9a012bf1bc6320403377c934998d3
4
- data.tar.gz: 1babbe0d881bd6f1823935cf6d66447cfa8f5a91df4106e9d87f1ac0fe792aac
3
+ metadata.gz: f325c36f3cd721eaeedafc552c28ae05aeaca61e1b28db412b1a43c7b1eb94b9
4
+ data.tar.gz: '08e087bd46c830537ff2302af6f9d0ec71003ea48836bb36f59890a41ef5a1da'
5
5
  SHA512:
6
- metadata.gz: efb801027685d7156f499f110028ffae75fac89032598bc447d2b1c6e1f4acd7fe61905a509e3d6faa4d5d74348257faa98adc3c69d6c1e90f5719a55b1dfac7
7
- data.tar.gz: 7bf47753113ba141a5e7798f40caa958f27534082484286d483d03fbcf8a1f6881c4ddb3cb1111154790a21bcee77eecfbc366e2af8b75ae261507985f3c3dd4
6
+ metadata.gz: 416f1458f279a4a1c6e4c69ee55997fd36c133ff72ffa12b584777e4f60baffcf5327c0e685dd21c7f02c84d85a2c3152137784d86354e0cfe59abbd93aaf2eb
7
+ data.tar.gz: 8b63487982fe8884a9ad220e707c847a03cad7d1aada0e0d9ad156492cb65e51d027063e9320e5898335ecf26b4b7eb9f3c066ba58539815538764dfe32a7e2b
@@ -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