open_api_import 0.11.6 → 0.12.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/README.md +25 -2
- data/bin/open_api_import +25 -11
- data/lib/open_api_import/filter.rb +10 -6
- data/lib/open_api_import/get_data_all_of_bodies.rb +8 -4
- data/lib/open_api_import/get_examples.rb +52 -50
- data/lib/open_api_import/get_patterns.rb +35 -27
- data/lib/open_api_import/get_required_data.rb +12 -7
- data/lib/open_api_import/get_response_examples.rb +28 -28
- data/lib/open_api_import/open_api_import.rb +232 -187
- data/lib/open_api_import/pretty_hash_symbolized.rb +8 -4
- data/lib/open_api_import/utils.rb +17 -19
- data/lib/open_api_import.rb +3 -3
- metadata +40 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41480087861a00b2fce54a5096291bcfa12db19f719cfcf1e133b069610c4786
|
|
4
|
+
data.tar.gz: c02407e9c86894f23aea9c3ba28522ddb91f0c1957722a7d51cd99c231f6ff9d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e7bbc02cd6f7abed67c1476da7f83bce7d4ad5a538453c300059824d24f68816e511a8c7ce19d2274d011b7e1364d5c58455b600f734f76a82790fd55220422c
|
|
7
|
+
data.tar.gz: 43cfb5083b2188484dae5d2b637c75774915fd75356a95425ca252dde067da7863a9db68269271ec46e71100a5083818ce529a270bd16ff2f37d4f21a3e728e9
|
data/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# OpenApiImport
|
|
2
2
|
|
|
3
3
|
[](https://rubygems.org/gems/open_api_import)
|
|
4
|
-
[](https://github.com/MarioRuiz/open_api_import/actions/workflows/ci.yml)
|
|
5
5
|
[](https://coveralls.io/github/MarioRuiz/open_api_import?branch=master)
|
|
6
6
|
|
|
7
|
-
Import a Swagger or Open API file and create a Ruby Request Hash file including all requests and responses with all the examples. The file can be in JSON or YAML.
|
|
7
|
+
Import a Swagger or Open API file (including Open API 3.1) and create a Ruby Request Hash file including all requests and responses with all the examples. The file can be in JSON or YAML.
|
|
8
8
|
|
|
9
9
|
The Request Hash will include also the pattern (regular expressions) of the fields, parameters, default values...
|
|
10
10
|
|
|
@@ -68,6 +68,10 @@ This is the output of the previous run:
|
|
|
68
68
|
- Helper: ./spec/helper.rb
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
## Requirements
|
|
72
|
+
|
|
73
|
+
- Ruby >= 3.0
|
|
74
|
+
|
|
71
75
|
## Installation
|
|
72
76
|
|
|
73
77
|
Install it yourself as:
|
|
@@ -102,6 +106,7 @@ More info: https://github.com/MarioRuiz/open_api_import
|
|
|
102
106
|
In case no options supplied:
|
|
103
107
|
* It will be used the value of operation_id on snake_case for the name of the methods
|
|
104
108
|
* It will be used the first folder of the path to create the module name
|
|
109
|
+
-v, --version Display the version
|
|
105
110
|
-n, --no_responses if you don't want to add the examples of responses in the resultant file.
|
|
106
111
|
-m, --mock Add the first response on the request as mock_response
|
|
107
112
|
-p, --path_method it will be used the path and http method to create the method names
|
|
@@ -111,6 +116,7 @@ In case no options supplied:
|
|
|
111
116
|
-F, --fixed_module all the requests will be under the module Requests
|
|
112
117
|
-s, --silent It will display only errors
|
|
113
118
|
-c, --create_constants For required arguments, it will create keyword arguments assigning by default a constant.
|
|
119
|
+
-d, --dry_run Preview the generated output without writing files
|
|
114
120
|
```
|
|
115
121
|
|
|
116
122
|
|
|
@@ -490,6 +496,23 @@ It will include this on the output file:
|
|
|
490
496
|
...
|
|
491
497
|
```
|
|
492
498
|
|
|
499
|
+
### return_data
|
|
500
|
+
|
|
501
|
+
Instead of writing files to disk, return a Hash of `{filename => content}`. This is useful for previewing the output or programmatically processing the generated code.
|
|
502
|
+
|
|
503
|
+
Accepts true or false, by default is false.
|
|
504
|
+
|
|
505
|
+
```ruby
|
|
506
|
+
require 'open_api_import'
|
|
507
|
+
|
|
508
|
+
result = OpenApiImport.from "./spec/fixtures/v2.0/yaml/petstore-simple.yaml", return_data: true
|
|
509
|
+
|
|
510
|
+
result.each do |filepath, content|
|
|
511
|
+
puts "--- #{filepath} ---"
|
|
512
|
+
puts content
|
|
513
|
+
end
|
|
514
|
+
```
|
|
515
|
+
|
|
493
516
|
### create_constants
|
|
494
517
|
|
|
495
518
|
The methods will be generated using keyword arguments and for required arguments, it will create keyword arguments assigning by default a constant.
|
data/bin/open_api_import
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
-
require
|
|
3
|
-
require
|
|
2
|
+
require "optparse"
|
|
3
|
+
require "open_api_import"
|
|
4
4
|
|
|
5
5
|
options = {
|
|
6
6
|
name_for_module: :path
|
|
@@ -8,12 +8,17 @@ options = {
|
|
|
8
8
|
|
|
9
9
|
optparse = OptionParser.new do |opts|
|
|
10
10
|
opts.banner = "Usage: open_api_import [open_api_file] [options]\n"
|
|
11
|
-
opts.banner+= "Import a Swagger or Open API file and create a Ruby Request Hash file including all requests and responses.\n"
|
|
12
|
-
opts.banner+= "More info: https://github.com/MarioRuiz/open_api_import\n\n"
|
|
13
|
-
opts.banner+= "In case no options supplied: \n"
|
|
14
|
-
opts.banner+= " * It will be used the value of operation_id on snake_case for the name of the methods\n"
|
|
15
|
-
opts.banner+= " * It will be used the first folder of the path to create the module name\n"
|
|
16
|
-
|
|
11
|
+
opts.banner += "Import a Swagger or Open API file and create a Ruby Request Hash file including all requests and responses.\n"
|
|
12
|
+
opts.banner += "More info: https://github.com/MarioRuiz/open_api_import\n\n"
|
|
13
|
+
opts.banner += "In case no options supplied: \n"
|
|
14
|
+
opts.banner += " * It will be used the value of operation_id on snake_case for the name of the methods\n"
|
|
15
|
+
opts.banner += " * It will be used the first folder of the path to create the module name\n"
|
|
16
|
+
|
|
17
|
+
opts.on("-v", "--version", "Display the version") do
|
|
18
|
+
puts "open_api_import #{OpenApiImport::VERSION}"
|
|
19
|
+
exit
|
|
20
|
+
end
|
|
21
|
+
|
|
17
22
|
opts.on("-n", "--no_responses", "if you don't want to add the examples of responses in the resultant file.") do
|
|
18
23
|
options[:include_responses] = false
|
|
19
24
|
end
|
|
@@ -50,7 +55,9 @@ optparse = OptionParser.new do |opts|
|
|
|
50
55
|
options[:create_constants] = true
|
|
51
56
|
end
|
|
52
57
|
|
|
53
|
-
|
|
58
|
+
opts.on("-d", "--dry_run", "Preview the generated output without writing files") do
|
|
59
|
+
options[:return_data] = true
|
|
60
|
+
end
|
|
54
61
|
end
|
|
55
62
|
|
|
56
63
|
optparse.parse!
|
|
@@ -65,9 +72,16 @@ if options.key?(:create_files)
|
|
|
65
72
|
end
|
|
66
73
|
|
|
67
74
|
filename = ARGV.pop
|
|
68
|
-
if filename.to_s==
|
|
75
|
+
if filename.to_s == ""
|
|
69
76
|
puts optparse
|
|
70
77
|
puts "** Need to specify at least a file to import."
|
|
71
78
|
else
|
|
72
|
-
OpenApiImport.from filename, **options
|
|
79
|
+
result = OpenApiImport.from filename, **options
|
|
80
|
+
if options[:return_data] && result.is_a?(Hash)
|
|
81
|
+
result.each do |filepath, content|
|
|
82
|
+
puts "--- #{filepath} ---"
|
|
83
|
+
puts content
|
|
84
|
+
puts
|
|
85
|
+
end
|
|
86
|
+
end
|
|
73
87
|
end
|
|
@@ -1,28 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module LibOpenApiImport
|
|
2
|
-
|
|
4
|
+
private
|
|
5
|
+
|
|
3
6
|
def filter(hash, keys, nested = false)
|
|
4
7
|
result = {}
|
|
5
8
|
keys = [keys] unless keys.is_a?(Array)
|
|
6
9
|
if nested
|
|
7
10
|
result = hash.nice_filter(keys)
|
|
8
11
|
else
|
|
9
|
-
#to be backwards compatible
|
|
10
12
|
keys.each do |k|
|
|
11
|
-
if k.is_a?(Symbol)
|
|
13
|
+
if k.is_a?(Symbol) && hash.key?(k)
|
|
12
14
|
if hash[k].is_a?(Hash)
|
|
13
15
|
result[k] = {}
|
|
14
16
|
else
|
|
15
17
|
result[k] = hash[k]
|
|
16
18
|
end
|
|
17
|
-
elsif k.is_a?(Symbol)
|
|
19
|
+
elsif k.is_a?(Symbol) && k.to_s.include?(".") && hash.key?(k.to_s.scan(/(\w+)\./).join.to_sym)
|
|
18
20
|
kn = k.to_s.split(".")
|
|
19
21
|
vn = kn[1].to_sym
|
|
22
|
+
result[kn.first.to_sym] ||= {}
|
|
20
23
|
result[kn.first.to_sym][vn] = filter(hash[kn.first.to_sym], vn).values[0]
|
|
21
|
-
elsif k.is_a?(Hash)
|
|
24
|
+
elsif k.is_a?(Hash) && hash.key?(k.keys[0])
|
|
25
|
+
result[k.keys[0]] ||= {}
|
|
22
26
|
result[k.keys[0]][k.values[0]] = filter(hash[k.keys[0]], k.values[0]).values[0]
|
|
23
27
|
end
|
|
24
28
|
end
|
|
25
29
|
end
|
|
26
|
-
|
|
30
|
+
result
|
|
27
31
|
end
|
|
28
32
|
end
|
|
@@ -1,22 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module LibOpenApiImport
|
|
2
|
-
private
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
def get_data_all_of_bodies(p)
|
|
3
7
|
bodies = []
|
|
4
8
|
data_examples_all_of = false
|
|
5
9
|
if p.is_a?(Array)
|
|
6
10
|
q = p
|
|
7
|
-
elsif p.key?(:schema)
|
|
11
|
+
elsif p.key?(:schema) && p[:schema].key?(:allOf)
|
|
8
12
|
q = p[:schema][:allOf]
|
|
9
13
|
else
|
|
10
14
|
q = [p]
|
|
11
15
|
end
|
|
12
16
|
q.each do |pt|
|
|
13
|
-
if pt.is_a?(Hash)
|
|
17
|
+
if pt.is_a?(Hash) && pt.key?(:allOf)
|
|
14
18
|
bodies += get_data_all_of_bodies(pt[:allOf])[1]
|
|
15
19
|
data_examples_all_of = true
|
|
16
20
|
else
|
|
17
21
|
bodies << pt
|
|
18
22
|
end
|
|
19
23
|
end
|
|
20
|
-
|
|
24
|
+
[data_examples_all_of, bodies]
|
|
21
25
|
end
|
|
22
26
|
end
|
|
@@ -1,34 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module LibOpenApiImport
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
def get_examples(properties, type = :key_value, remove_readonly = false)
|
|
5
7
|
example = []
|
|
6
|
-
example << "{" unless properties.empty?
|
|
8
|
+
example << "{" unless properties.empty? || (type == :only_value)
|
|
7
9
|
properties.each do |prop, val|
|
|
8
|
-
unless remove_readonly
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
unless remove_readonly && val.key?(:readOnly) && (val[:readOnly] == true)
|
|
11
|
+
effective_type = val[:type]
|
|
12
|
+
if val.key?(:properties) && !val.key?(:example) && !val.key?(:type)
|
|
13
|
+
effective_type = "object"
|
|
11
14
|
end
|
|
12
|
-
if val.key?(:items)
|
|
13
|
-
|
|
15
|
+
if val.key?(:items) && !val.key?(:example) && !val.key?(:type)
|
|
16
|
+
effective_type = "array"
|
|
14
17
|
end
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
|
|
19
|
+
effective_type = Array(effective_type).reject { |t| t == "null" }.first if effective_type.is_a?(Array)
|
|
20
|
+
|
|
21
|
+
effective_example = val[:example]
|
|
22
|
+
effective_example ||= val[:examples]&.first if val.key?(:examples) && val[:examples].is_a?(Array) && !val[:examples].empty?
|
|
23
|
+
|
|
24
|
+
if effective_example
|
|
25
|
+
if effective_example.is_a?(Array) && val.key?(:type) && (val[:type] == "string")
|
|
26
|
+
example << " #{prop.to_sym}: \"#{effective_example[0]}\", "
|
|
27
|
+
elsif effective_example.is_a?(String)
|
|
28
|
+
escaped = effective_example.include?("'") ? effective_example : effective_example.gsub('"', "'")
|
|
29
|
+
example << " #{prop.to_sym}: \"#{escaped}\", "
|
|
30
|
+
elsif effective_example.is_a?(Time)
|
|
31
|
+
example << " #{prop.to_sym}: \"#{effective_example}\", "
|
|
18
32
|
else
|
|
19
|
-
|
|
20
|
-
val[:example].gsub!('"', "'") unless val.include?("'")
|
|
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
|
|
33
|
+
example << " #{prop.to_sym}: #{effective_example}, "
|
|
27
34
|
end
|
|
28
|
-
elsif
|
|
35
|
+
elsif effective_type
|
|
29
36
|
format = val[:format]
|
|
30
|
-
format =
|
|
31
|
-
case
|
|
37
|
+
format = effective_type if format.to_s == ""
|
|
38
|
+
case effective_type.downcase
|
|
32
39
|
when "string"
|
|
33
40
|
example << " #{prop.to_sym}: \"#{format}\", "
|
|
34
41
|
when "integer"
|
|
@@ -36,61 +43,56 @@ module LibOpenApiImport
|
|
|
36
43
|
when "number"
|
|
37
44
|
format_name = format.to_s.downcase
|
|
38
45
|
number_value = if %w[float double decimal].include?(format_name)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
"0.0"
|
|
47
|
+
else
|
|
48
|
+
"0"
|
|
49
|
+
end
|
|
43
50
|
example << " #{prop.to_sym}: #{number_value}, "
|
|
44
51
|
when "boolean"
|
|
45
52
|
example << " #{prop.to_sym}: true, "
|
|
46
53
|
when "array"
|
|
47
|
-
if val.key?(:items)
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
items_enum = if val.key?(:items) && val[:items].is_a?(Hash) && (val[:items].size == 1) && val[:items].key?(:type)
|
|
55
|
+
[val[:items][:type]]
|
|
56
|
+
elsif val.key?(:items) && !val[:items].nil? && val[:items].key?(:enum)
|
|
57
|
+
val[:items][:enum]
|
|
58
|
+
end
|
|
50
59
|
|
|
51
|
-
if
|
|
52
|
-
#before we were getting in all these cases a random value from the enum, now we are getting the first position by default
|
|
53
|
-
#the reason is to avoid confusion later in case we want to compare two swaggers and verify the changes
|
|
60
|
+
if items_enum
|
|
54
61
|
if type == :only_value
|
|
55
|
-
if
|
|
56
|
-
example << " [\"
|
|
62
|
+
if items_enum[0].is_a?(String)
|
|
63
|
+
example << " [\"#{items_enum[0]}\"] "
|
|
57
64
|
else
|
|
58
|
-
example << " [
|
|
65
|
+
example << " [#{items_enum[0]}] "
|
|
59
66
|
end
|
|
67
|
+
elsif items_enum[0].is_a?(String)
|
|
68
|
+
example << " #{prop.to_sym}: [\"#{items_enum[0]}\"], "
|
|
60
69
|
else
|
|
61
|
-
|
|
62
|
-
example << " #{prop.to_sym}: [\"" + val[:items][:enum][0] + "\"], "
|
|
63
|
-
else
|
|
64
|
-
example << " #{prop.to_sym}: [" + val[:items][:enum][0] + "], "
|
|
65
|
-
end
|
|
70
|
+
example << " #{prop.to_sym}: [#{items_enum[0]}], "
|
|
66
71
|
end
|
|
67
72
|
else
|
|
68
|
-
#todo: differ between response examples and data examples
|
|
69
73
|
examplet = get_response_examples({ schema: val }, remove_readonly).join("\n")
|
|
70
|
-
examplet =
|
|
74
|
+
examplet = "[]" if examplet.empty?
|
|
71
75
|
if type == :only_value
|
|
72
76
|
example << examplet
|
|
73
77
|
else
|
|
74
|
-
example << " #{prop.to_sym}:
|
|
75
|
-
end
|
|
76
|
-
|
|
78
|
+
example << " #{prop.to_sym}: #{examplet}, "
|
|
79
|
+
end
|
|
77
80
|
end
|
|
78
81
|
when "object"
|
|
79
|
-
#todo: differ between response examples and data examples
|
|
80
82
|
res_ex = get_response_examples({ schema: val }, remove_readonly)
|
|
81
|
-
if res_ex.
|
|
83
|
+
if res_ex.empty?
|
|
82
84
|
res_ex = "{ }"
|
|
83
85
|
else
|
|
84
86
|
res_ex = res_ex.join("\n")
|
|
85
87
|
end
|
|
86
|
-
example << " #{prop.to_sym}:
|
|
88
|
+
example << " #{prop.to_sym}: #{res_ex}, "
|
|
87
89
|
else
|
|
88
90
|
example << " #{prop.to_sym}: \"#{format}\", "
|
|
89
91
|
end
|
|
90
92
|
end
|
|
91
93
|
end
|
|
92
94
|
end
|
|
93
|
-
example << "}" unless properties.empty?
|
|
95
|
+
example << "}" unless properties.empty? || (type == :only_value)
|
|
94
96
|
example
|
|
95
97
|
end
|
|
96
98
|
end
|
|
@@ -1,69 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module LibOpenApiImport
|
|
2
|
-
|
|
3
|
-
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
def get_patterns(dpk, dpv)
|
|
4
7
|
data_pattern = []
|
|
8
|
+
effective_type = dpv[:type]
|
|
9
|
+
effective_type = Array(effective_type).reject { |t| t == "null" }.first if effective_type.is_a?(Array)
|
|
10
|
+
|
|
5
11
|
if dpv.keys.include?(:pattern)
|
|
6
|
-
#todo: control better the cases with back slashes
|
|
7
12
|
if dpv[:pattern].include?('\\\\/')
|
|
8
|
-
#for cases like this: ^[^\.\\/:*?"<>|][^\\/:*?"<>|]{0,13}[^\.\\/:*?"<>|]?$
|
|
9
13
|
data_pattern << "'#{dpk}': /#{dpv[:pattern].to_s.gsub('\/', "/")}/"
|
|
10
|
-
elsif dpv[:pattern].match?(/\\x[0-9ABCDEF][0-9ABCDEF]
|
|
14
|
+
elsif dpv[:pattern].match?(/\\x[0-9ABCDEF][0-9ABCDEF]-/)
|
|
11
15
|
data_pattern << "'#{dpk}': /#{dpv[:pattern].to_s.gsub('\\x', '\\u00')}/"
|
|
12
16
|
elsif dpv[:pattern].include?('\\x')
|
|
13
17
|
data_pattern << "'#{dpk}': /#{dpv[:pattern].to_s.gsub('\\x', '\\u')}/"
|
|
14
18
|
else
|
|
15
|
-
data_pattern << "'#{dpk}': /#{dpv[:pattern]
|
|
19
|
+
data_pattern << "'#{dpk}': /#{dpv[:pattern]}/"
|
|
16
20
|
end
|
|
17
|
-
elsif dpv.key?(:minLength)
|
|
21
|
+
elsif dpv.key?(:minLength) && dpv.key?(:maxLength)
|
|
18
22
|
data_pattern << "'#{dpk}': :'#{dpv[:minLength]}-#{dpv[:maxLength]}:LN$'"
|
|
19
|
-
elsif dpv.key?(:minLength)
|
|
23
|
+
elsif dpv.key?(:minLength) && !dpv.key?(:maxLength)
|
|
20
24
|
data_pattern << "'#{dpk}': :'#{dpv[:minLength]}:LN$'"
|
|
21
|
-
elsif !dpv.key?(:minLength)
|
|
25
|
+
elsif !dpv.key?(:minLength) && dpv.key?(:maxLength)
|
|
22
26
|
data_pattern << "'#{dpk}': :'0-#{dpv[:maxLength]}:LN$'"
|
|
23
|
-
elsif dpv.key?(:minimum)
|
|
27
|
+
elsif dpv.key?(:minimum) && dpv.key?(:maximum) && (effective_type == "string")
|
|
24
28
|
data_pattern << "'#{dpk}': :'#{dpv[:minimum]}-#{dpv[:maximum]}:LN$'"
|
|
25
|
-
elsif dpv.key?(:minimum)
|
|
29
|
+
elsif dpv.key?(:minimum) && dpv.key?(:maximum)
|
|
26
30
|
data_pattern << "'#{dpk}': #{dpv[:minimum]}..#{dpv[:maximum]}"
|
|
27
|
-
elsif dpv.key?(:minimum)
|
|
28
|
-
if RUBY_VERSION >= "2.6.0"
|
|
31
|
+
elsif dpv.key?(:minimum) && !dpv.key?(:maximum)
|
|
32
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.6.0")
|
|
29
33
|
data_pattern << "'#{dpk}': #{dpv[:minimum]}.. "
|
|
30
34
|
else
|
|
31
35
|
data_pattern << "#'#{dpk}': #{dpv[:minimum]}.. # INFINITE only working on ruby>=2.6.0"
|
|
32
36
|
end
|
|
33
|
-
elsif !dpv.key?(:minimum)
|
|
37
|
+
elsif !dpv.key?(:minimum) && dpv.key?(:maximum)
|
|
34
38
|
data_pattern << "'#{dpk}': 0..#{dpv[:maximum]}"
|
|
35
39
|
elsif dpv[:format] == "date-time"
|
|
36
40
|
data_pattern << "'#{dpk}': DateTime"
|
|
37
|
-
elsif
|
|
41
|
+
elsif effective_type == "boolean"
|
|
38
42
|
data_pattern << "'#{dpk}': Boolean"
|
|
39
43
|
elsif dpv.key?(:enum)
|
|
40
44
|
data_pattern << "'#{dpk}': :'#{dpv[:enum].join("|")}'"
|
|
41
|
-
elsif
|
|
42
|
-
#{:title=>"Balala", :type=>"array", :items=>{:type=>"string", :enum=>["uno","dos"], :example=>"uno"}}
|
|
45
|
+
elsif (effective_type == "array") && dpv.key?(:items) && dpv[:items].is_a?(Hash) && dpv[:items].key?(:enum) && dpv[:items][:enum].is_a?(Array)
|
|
43
46
|
data_pattern << "'#{dpk}': [:'#{dpv[:items][:enum].join("|")}']"
|
|
44
|
-
elsif
|
|
45
|
-
#{:title=>"Balala", :type=>"array", :items=>{title: 'xxxx, properties: {server: {enum:['ibm','msa','pytan']}}}
|
|
47
|
+
elsif (effective_type == "array") && dpv.key?(:items) && dpv[:items].is_a?(Hash) && !dpv[:items].key?(:enum) && dpv[:items].key?(:properties)
|
|
46
48
|
dpv[:items][:properties].each do |dpkk, dpvv|
|
|
47
49
|
if dpk == ""
|
|
48
|
-
data_pattern += get_patterns(
|
|
50
|
+
data_pattern += get_patterns(dpkk.to_s, dpvv)
|
|
49
51
|
else
|
|
50
52
|
data_pattern += get_patterns("#{dpk}.#{dpkk}", dpvv)
|
|
51
53
|
end
|
|
52
54
|
end
|
|
53
|
-
elsif
|
|
54
|
-
!dpv[:items].key?(:enum)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
elsif (effective_type == "array") && dpv.key?(:items) && dpv[:items].is_a?(Hash) &&
|
|
56
|
+
!dpv[:items].key?(:enum) && !dpv[:items].key?(:properties) && dpv[:items].key?(:type)
|
|
57
|
+
result = get_patterns("", dpv[:items])
|
|
58
|
+
if result.empty?
|
|
59
|
+
item_type = dpv[:items][:type]
|
|
60
|
+
item_type = Array(item_type).reject { |t| t == "null" }.first if item_type.is_a?(Array)
|
|
61
|
+
data_pattern << "'#{dpk}': [:'#{item_type}']"
|
|
62
|
+
else
|
|
63
|
+
data_pattern << "'#{dpk}': [ #{result.join[4..]} ]"
|
|
64
|
+
end
|
|
65
|
+
elsif (effective_type == "object") && dpv.key?(:properties)
|
|
58
66
|
dpv[:properties].each do |dpkk, dpvv|
|
|
59
67
|
if dpk == ""
|
|
60
|
-
data_pattern += get_patterns(
|
|
68
|
+
data_pattern += get_patterns(dpkk.to_s, dpvv)
|
|
61
69
|
else
|
|
62
70
|
data_pattern += get_patterns("#{dpk}.#{dpkk}", dpvv)
|
|
63
71
|
end
|
|
64
72
|
end
|
|
65
73
|
end
|
|
66
74
|
data_pattern.uniq!
|
|
67
|
-
|
|
75
|
+
data_pattern
|
|
68
76
|
end
|
|
69
77
|
end
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module LibOpenApiImport
|
|
2
|
-
|
|
3
|
-
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
def get_required_data(body)
|
|
4
7
|
data_required = []
|
|
5
|
-
if body.
|
|
8
|
+
if body.key?(:required) && body[:required].size.positive?
|
|
6
9
|
body[:required].each do |r|
|
|
7
10
|
data_required << r.to_sym
|
|
8
11
|
end
|
|
@@ -16,15 +19,17 @@ module LibOpenApiImport
|
|
|
16
19
|
end
|
|
17
20
|
end
|
|
18
21
|
end
|
|
22
|
+
nested_required = []
|
|
19
23
|
data_required.each do |key|
|
|
20
|
-
if body.key?(:properties)
|
|
21
|
-
body[:properties][key].key?(:required)
|
|
24
|
+
if body.key?(:properties) && body[:properties][key].is_a?(Hash) &&
|
|
25
|
+
body[:properties][key].key?(:required) && body[:properties][key][:required].size.positive?
|
|
22
26
|
dr = get_required_data(body[:properties][key])
|
|
23
27
|
dr.each do |k|
|
|
24
|
-
|
|
28
|
+
nested_required << :"#{key}.#{k}"
|
|
25
29
|
end
|
|
26
30
|
end
|
|
27
31
|
end
|
|
28
|
-
|
|
32
|
+
data_required.concat(nested_required)
|
|
33
|
+
data_required
|
|
29
34
|
end
|
|
30
35
|
end
|
|
@@ -1,38 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module LibOpenApiImport
|
|
4
|
+
private
|
|
5
|
+
|
|
2
6
|
# Retrieve the response examples from the hash
|
|
3
|
-
|
|
7
|
+
def get_response_examples(v, remove_readonly = false)
|
|
4
8
|
# TODO: take in consideration the case allOf, oneOf... schema.items.allOf[0].properties schema.items.allOf[1].properties
|
|
5
9
|
# example on https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/yaml/petstore-expanded.yaml
|
|
6
10
|
v = v.dup
|
|
7
|
-
response_example =
|
|
11
|
+
response_example = []
|
|
8
12
|
# for open api 3.0 with responses schema inside content
|
|
9
|
-
if v.key?(:content) && v[:content].is_a?(Hash) && v[:content].key?(:
|
|
10
|
-
v[:content][:
|
|
11
|
-
v = v[:content][:
|
|
13
|
+
if v.key?(:content) && v[:content].is_a?(Hash) && v[:content].key?(:"application/json") &&
|
|
14
|
+
v[:content][:"application/json"].key?(:schema)
|
|
15
|
+
v = v[:content][:"application/json"].dup
|
|
12
16
|
end
|
|
13
|
-
if v.key?(:examples) && v[:examples].is_a?(Hash) && v[:examples].key?(:
|
|
14
|
-
if v[:examples][:
|
|
15
|
-
response_example << v[:examples][:
|
|
16
|
-
elsif v[:examples][:
|
|
17
|
-
exs = v[:examples][:
|
|
17
|
+
if v.key?(:examples) && v[:examples].is_a?(Hash) && v[:examples].key?(:"application/json")
|
|
18
|
+
if v[:examples][:"application/json"].is_a?(String)
|
|
19
|
+
response_example << v[:examples][:"application/json"]
|
|
20
|
+
elsif v[:examples][:"application/json"].is_a?(Hash)
|
|
21
|
+
exs = v[:examples][:"application/json"].to_s
|
|
18
22
|
exs.gsub!(/:(\w+)=>/, "\n\\1: ")
|
|
19
23
|
response_example << exs
|
|
20
|
-
elsif v[:examples][:
|
|
24
|
+
elsif v[:examples][:"application/json"].is_a?(Array)
|
|
21
25
|
response_example << "["
|
|
22
|
-
v[:examples][:
|
|
26
|
+
v[:examples][:"application/json"].each do |ex|
|
|
23
27
|
exs = ex.to_s
|
|
24
28
|
if ex.is_a?(Hash)
|
|
25
29
|
exs.gsub!(/:(\w+)=>/, "\n\\1: ")
|
|
26
30
|
end
|
|
27
|
-
response_example <<
|
|
31
|
+
response_example << "#{exs}, "
|
|
28
32
|
end
|
|
29
33
|
response_example << "]"
|
|
30
34
|
end
|
|
31
35
|
# 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?(:
|
|
33
|
-
v[:content][:
|
|
34
|
-
v[:content][:
|
|
35
|
-
#
|
|
36
|
+
elsif v.key?(:content) && v[:content].is_a?(Hash) && v[:content].key?(:"application/json") &&
|
|
37
|
+
v[:content][:"application/json"].key?(:examples)
|
|
38
|
+
v[:content][:"application/json"][:examples].each_value do |tv|
|
|
39
|
+
# TODO: for the moment we only take in consideration the first example of response.
|
|
36
40
|
# we need to decide how to manage to do it correctly
|
|
37
41
|
if tv.key?(:value)
|
|
38
42
|
tresp = tv[:value]
|
|
@@ -52,11 +56,11 @@ module LibOpenApiImport
|
|
|
52
56
|
if ex.is_a?(Hash)
|
|
53
57
|
exs.gsub!(/:(\w+)=>/, "\n\\1: ")
|
|
54
58
|
end
|
|
55
|
-
response_example <<
|
|
59
|
+
response_example << "#{exs}, "
|
|
56
60
|
end
|
|
57
61
|
response_example << "]"
|
|
58
62
|
end
|
|
59
|
-
break #only the first one it is considered
|
|
63
|
+
break # only the first one it is considered
|
|
60
64
|
end
|
|
61
65
|
elsif v.key?(:schema) && v[:schema].is_a?(Hash) &&
|
|
62
66
|
(v[:schema].key?(:properties) ||
|
|
@@ -82,23 +86,19 @@ module LibOpenApiImport
|
|
|
82
86
|
|
|
83
87
|
response_example += get_examples(properties, :key_value, remove_readonly) unless properties.empty?
|
|
84
88
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
#
|
|
88
|
-
else # array, items
|
|
89
|
-
response_example << "]"
|
|
90
|
-
end
|
|
89
|
+
if !response_example.empty? && !(v[:schema].key?(:properties) || v[:schema].key?(:allOf)) # array, items
|
|
90
|
+
response_example << "]"
|
|
91
91
|
end
|
|
92
|
-
elsif v.key?(:schema)
|
|
92
|
+
elsif v.key?(:schema) && v[:schema].key?(:items) && v[:schema][:items].is_a?(Hash) && v[:schema][:items].key?(:type)
|
|
93
93
|
# for the case only type supplied but nothing else for the array
|
|
94
94
|
response_example << "[\"#{v[:schema][:items][:type]}\"]"
|
|
95
95
|
end
|
|
96
96
|
response_example.each do |rs|
|
|
97
|
-
#(@type Google) for the case in example the key is something like: @type:
|
|
97
|
+
# (@type Google) for the case in example the key is something like: @type:
|
|
98
98
|
if rs.match?(/^\s*@\w+:/)
|
|
99
99
|
rs.gsub!(/@(\w+):/, '\'@\1\':')
|
|
100
100
|
end
|
|
101
101
|
end
|
|
102
|
-
|
|
102
|
+
response_example
|
|
103
103
|
end
|
|
104
104
|
end
|