swagger-to-rbs 0.2.0 → 0.3.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 +17 -7
- data/lib/swagger2_rbs/rest_endpoint.rb +26 -56
- data/lib/swagger2_rbs/rest_endpoint_typed.rb +74 -0
- data/lib/templates/http_client.rb.erb +4 -3
- data/lib/templates/http_client.rbs.erb +8 -6
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4609330c97363e8fc3f14d202f55904f026124a77a13c9e9bfcf8728a75aab42
|
4
|
+
data.tar.gz: 4ebb0337d6d72947aa3ce27ce4e2d8a99cbc63eb7f33a8015a3dccacb668696a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7899e345942d1014a68dccf6a866295a2afafefabc80d4a2abc439a15ab4f6bb35d7ab708f3ef4eb7b548602902b66c850d015fae56b3b4efdc7ab3c4dca5781
|
7
|
+
data.tar.gz: 58a8e1db7ae6b58d0e3e0611c4e4b6346e3871ee5556f3f01018d812eb2027703d2bfa3733f63c346304cfbd322b68ec316c8ecb031dfdb356be8a3075a9157a
|
data/README.md
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
|
1
|
+
## Install
|
2
|
+
|
3
|
+
```
|
4
|
+
gem install swagger-to-rbs
|
5
|
+
```
|
6
|
+
|
7
|
+
## Usage
|
2
8
|
|
3
9
|
Dowload swagger spec
|
4
10
|
|
@@ -11,7 +17,7 @@ curl https://petstore3.swagger.io/api/v3/openapi.json > swagger.json
|
|
11
17
|
Generate http client based on [Httparty gem](https://github.com/jnunemaker/httparty)
|
12
18
|
|
13
19
|
```
|
14
|
-
swagger-to-rbs generate --name
|
20
|
+
swagger-to-rbs generate --name PetApi --spec swagger.json
|
15
21
|
```
|
16
22
|
|
17
23
|
Result:
|
@@ -24,16 +30,20 @@ class PetApi
|
|
24
30
|
base_uri "/api/v3"
|
25
31
|
#...
|
26
32
|
|
27
|
-
def
|
28
|
-
self.class.
|
33
|
+
def initialize
|
34
|
+
self.class.headers({ 'Content-Type' => 'application/json' })
|
35
|
+
end
|
36
|
+
|
37
|
+
def getPetById(petId, options = {})
|
38
|
+
self.class.get("/pet/#{petId}", options)
|
29
39
|
end
|
30
40
|
|
31
41
|
def updatePet(body, options = {})
|
32
|
-
self.class.put("/pet", body: body.to_json
|
42
|
+
self.class.put("/pet", { body: body.to_json }.merge(options))
|
33
43
|
end
|
34
44
|
|
35
45
|
def addPet(body, options = {})
|
36
|
-
self.class.post("/pet", body: body.to_json
|
46
|
+
self.class.post("/pet", { body: body.to_json }.merge(options))
|
37
47
|
end
|
38
48
|
#...
|
39
49
|
end
|
@@ -44,7 +54,7 @@ end
|
|
44
54
|
Authorization example:
|
45
55
|
|
46
56
|
```
|
47
|
-
api =
|
57
|
+
api = PetApi.new
|
48
58
|
|
49
59
|
MyApi.headers(Authorization: "Bearer #{access_token}")
|
50
60
|
MyApi.base_uri("http://otherurl.test/api/v1)
|
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'slugify'
|
2
|
+
require_relative 'rest_endpoint_typed'
|
2
3
|
|
3
4
|
module Swagger2Rbs
|
4
5
|
class RestEndpoint
|
5
6
|
attr_reader :path, :method, :props
|
7
|
+
include RestEndpointTyped
|
6
8
|
|
7
9
|
def initialize(path, method, props)
|
8
10
|
@path = path
|
@@ -13,14 +15,28 @@ module Swagger2Rbs
|
|
13
15
|
def to_h
|
14
16
|
{
|
15
17
|
path: path_with_parameters,
|
18
|
+
http_method: method,
|
19
|
+
parameters_for_method: parameters_for_method,
|
20
|
+
typed_parameters_for_method: typed_parameters_for_method,
|
21
|
+
has_body: body?,
|
22
|
+
method_name: method_name,
|
23
|
+
response_typed: response_typed,
|
24
|
+
}
|
25
|
+
rescue => e
|
26
|
+
raise e, "Context: #{path} #{method} Message: #{e.message}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def body?
|
30
|
+
body && !body.empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_yaml
|
34
|
+
{
|
35
|
+
path: path,
|
16
36
|
method: method,
|
17
37
|
parameters: parameters,
|
18
|
-
parameters_for_method: parameters_for_method,
|
19
|
-
parameters_typed: parameters_typed,
|
20
38
|
method_name: method_name,
|
21
39
|
body: body,
|
22
|
-
body_typed: body_typed,
|
23
|
-
response_typed: response_typed,
|
24
40
|
}
|
25
41
|
rescue => e
|
26
42
|
raise e, "Context: #{path} #{method} Message: #{e.message}"
|
@@ -37,39 +53,7 @@ module Swagger2Rbs
|
|
37
53
|
def parameters
|
38
54
|
return [] unless props["parameters"]
|
39
55
|
|
40
|
-
props["parameters"]
|
41
|
-
end
|
42
|
-
|
43
|
-
def response_typed
|
44
|
-
schema = resolve_all_of(@props.dig("responses", "200", "content", "application/json", "schema"))
|
45
|
-
schema_to_typed(schema, {})
|
46
|
-
end
|
47
|
-
|
48
|
-
def parameters_typed
|
49
|
-
return nil if method != "get"
|
50
|
-
parameters.map{|it| "String #{it}" }
|
51
|
-
.push("?Hash[untyped, untyped] options")
|
52
|
-
.join(", ")
|
53
|
-
end
|
54
|
-
|
55
|
-
def body_typed
|
56
|
-
return nil if method != "post"
|
57
|
-
|
58
|
-
return "Hash[String, untyped]" unless body
|
59
|
-
return "Hash[String, untyped]" if body.empty?
|
60
|
-
|
61
|
-
"{" + body.map{ |k, v| to_typed(k, v) }.join(", ") + "}" + " body, ?Hash[untyped, untyped] options"
|
62
|
-
end
|
63
|
-
|
64
|
-
def to_typed(k, v)
|
65
|
-
return "#{k}: #{v&.capitalize}" unless v.is_a?(Array) || v.is_a?(Hash)
|
66
|
-
return "#{k}: {#{v.map{ |k2, v2| to_typed(k2, v2) }.join(", ")}}" if v.is_a?(Hash)
|
67
|
-
|
68
|
-
if v[0]&.is_a?(Hash)
|
69
|
-
"#{k}: Array[{" + v[0].map{ |k, v| to_typed(k, v) }.join(", ") + "}]"
|
70
|
-
else
|
71
|
-
"#{k}: Array[#{v[0]&.capitalize}]"
|
72
|
-
end
|
56
|
+
props["parameters"]&.select{|it| it["in"] == "path"}&.map{|it| it["name"]}
|
73
57
|
end
|
74
58
|
|
75
59
|
def body
|
@@ -80,26 +64,12 @@ module Swagger2Rbs
|
|
80
64
|
end
|
81
65
|
|
82
66
|
def parameters_for_method
|
83
|
-
return parameters.push("options = {}").join(", ") if
|
67
|
+
return parameters.push("options = {}").join(", ") if method == "get"
|
84
68
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
return nil unless schema
|
90
|
-
|
91
|
-
schema["properties"]&.reduce(memo)do |memo, (k,v)|
|
92
|
-
if v["type"] == "object"
|
93
|
-
memo.merge({k => schema_to_typed(v, {})})
|
94
|
-
elsif v["type"] == "array"
|
95
|
-
if v.dig("items", "type") == "object"
|
96
|
-
memo.merge({k => [schema_to_typed(v["items"], {})] })
|
97
|
-
else
|
98
|
-
memo.merge({k => [v.dig("items", "type")] })
|
99
|
-
end
|
100
|
-
else
|
101
|
-
memo.merge({k => v["type"] })
|
102
|
-
end
|
69
|
+
if body&.empty?
|
70
|
+
parameters.push("options = {}").join(", ")
|
71
|
+
else
|
72
|
+
parameters.push("body").push("options = {}").join(", ")
|
103
73
|
end
|
104
74
|
end
|
105
75
|
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Swagger2Rbs
|
2
|
+
|
3
|
+
module RestEndpointTyped
|
4
|
+
def response_typed
|
5
|
+
schema = resolve_all_of(@props.dig("responses", "200", "content", "application/json", "schema"))
|
6
|
+
schema_to_typed(schema, {})
|
7
|
+
end
|
8
|
+
|
9
|
+
def typed_parameters_for_method
|
10
|
+
options_typed = "?Hash[untyped, untyped] options"
|
11
|
+
return "(#{options_typed})" unless body && parameters
|
12
|
+
return "(#{options_typed})" if body.empty? && parameters.empty?
|
13
|
+
|
14
|
+
typed_parameters = parameters&.map{|it| "String #{it}" } || []
|
15
|
+
|
16
|
+
typed_parameters.push("#{body_typed} body") if body?
|
17
|
+
|
18
|
+
"(#{typed_parameters.push(options_typed).join(', ')})"
|
19
|
+
end
|
20
|
+
|
21
|
+
def body_typed
|
22
|
+
return nil unless body?
|
23
|
+
typed = (body.is_a?(Array) ? body[0] : body)&.map{ |k, v| to_typed(k, v) }.join(', ')
|
24
|
+
if body.is_a?(Array)
|
25
|
+
"Array[{ #{typed} }]"
|
26
|
+
else
|
27
|
+
"{ #{typed} }"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def type_case(str)
|
32
|
+
case str
|
33
|
+
when "boolean"
|
34
|
+
"bool"
|
35
|
+
else
|
36
|
+
str&.capitalize
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_typed(k, v)
|
41
|
+
return "#{k}: #{type_case(v)}" unless v.is_a?(Array) || v.is_a?(Hash)
|
42
|
+
return "#{k}: {#{v.map{ |k2, v2| to_typed(k2, v2) }.join(", ")}}" if v.is_a?(Hash)
|
43
|
+
|
44
|
+
if v[0]&.is_a?(Hash)
|
45
|
+
"#{k}: Array[{" + v[0].map{ |k, v| to_typed(k, v) }.join(", ") + "}]"
|
46
|
+
else
|
47
|
+
"#{k}: Array[#{type_case(v[0])}]"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def schema_to_typed(schema, memo = {})
|
52
|
+
return nil unless schema
|
53
|
+
|
54
|
+
properties = schema["type"]["array"] ? schema["items"]["properties"] : schema["properties"]
|
55
|
+
|
56
|
+
result = properties&.reduce(memo)do |memo, (k,v)|
|
57
|
+
if v["type"] == "object"
|
58
|
+
memo.merge({k => schema_to_typed(v, {})})
|
59
|
+
elsif v["type"] == "array"
|
60
|
+
if v.dig("items", "type") == "object"
|
61
|
+
memo.merge({k => [schema_to_typed(v["items"], {})] })
|
62
|
+
else
|
63
|
+
memo.merge({k => [v.dig("items", "type")] })
|
64
|
+
end
|
65
|
+
else
|
66
|
+
memo.merge({k => v["type"] })
|
67
|
+
end
|
68
|
+
end
|
69
|
+
return [result] if schema["type"]["array"]
|
70
|
+
|
71
|
+
result
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
|
2
2
|
require 'httparty'
|
3
|
+
require 'json'
|
3
4
|
|
4
5
|
class <%= @module_name %>
|
5
6
|
include HTTParty
|
@@ -11,13 +12,13 @@ class <%= @module_name %>
|
|
11
12
|
end
|
12
13
|
<%- @data[:endpoints].each do |endpoint| -%>
|
13
14
|
|
14
|
-
<%-
|
15
|
+
<%- unless endpoint[:has_body] -%>
|
15
16
|
def <%= endpoint[:method_name] %>(<%= endpoint[:parameters_for_method] %>)
|
16
|
-
self.class.<%= endpoint[:
|
17
|
+
self.class.<%= endpoint[:http_method] %>("<%= endpoint[:path] %>", options)
|
17
18
|
end
|
18
19
|
<%- else -%>
|
19
20
|
def <%= endpoint[:method_name] %>(<%= endpoint[:parameters_for_method] %>)
|
20
|
-
self.class.<%= endpoint[:
|
21
|
+
self.class.<%= endpoint[:http_method] %>("<%= endpoint[:path] %>", { body: body.to_json }.merge(options))
|
21
22
|
end
|
22
23
|
<%- end -%>
|
23
24
|
<%- end -%>
|
@@ -1,16 +1,18 @@
|
|
1
|
-
|
2
1
|
# Classes
|
3
2
|
|
3
|
+
module HTTParty
|
4
|
+
class Response
|
5
|
+
def body: -> untyped
|
6
|
+
def success?: -> bool
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
4
10
|
class <%= @module_name %>
|
5
11
|
include HTTParty
|
6
12
|
|
7
13
|
def initialize: -> void
|
8
14
|
<%- @data[:endpoints].each do |endpoint| -%>
|
9
15
|
|
10
|
-
|
11
|
-
def <%= endpoint[:method_name] %>(<%= endpoint[:parameters_typed] %>) -> HTTParty::Response
|
12
|
-
<%- else -%>
|
13
|
-
def <%= endpoint[:method_name] %>(<%= endpoint[:body_typed] %>) -> HTTParty::Response
|
14
|
-
<%- end -%>
|
16
|
+
def <%= endpoint[:method_name] %>: <%= endpoint[:typed_parameters_for_method] %> -> HTTParty::Response
|
15
17
|
<%- end -%>
|
16
18
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swagger-to-rbs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Savignano
|
@@ -14,14 +14,14 @@ dependencies:
|
|
14
14
|
name: thor
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- lib/swagger2_rbs/cli.rb
|
53
53
|
- lib/swagger2_rbs/hash_helper.rb
|
54
54
|
- lib/swagger2_rbs/rest_endpoint.rb
|
55
|
+
- lib/swagger2_rbs/rest_endpoint_typed.rb
|
55
56
|
- lib/templates/http_client.rb.erb
|
56
57
|
- lib/templates/http_client.rbs.erb
|
57
58
|
homepage: https://github.com/MiguelSavignano/swagger-to-rbs
|