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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 651f699800da6263854e5f030b5b2e9084570686b17b92b164319c8c18dbe28f
4
- data.tar.gz: 23e3253fd8e999fa5042045c9548227e5addd97ed26fe230c0303850665a6d85
3
+ metadata.gz: 4609330c97363e8fc3f14d202f55904f026124a77a13c9e9bfcf8728a75aab42
4
+ data.tar.gz: 4ebb0337d6d72947aa3ce27ce4e2d8a99cbc63eb7f33a8015a3dccacb668696a
5
5
  SHA512:
6
- metadata.gz: 6ceb2196aaf7cb48385a7c3d200f45a1c28880385ce00da876a6dcb9d19c08ca1a991fbc461e5d026e4276f78266e8f5d3ccc444f26d6fb61c309b9e5edae73b
7
- data.tar.gz: 27fc3959ff9f6a56846322e03b14e83fd60a96659e006abfe23c6ccb069bd404e4a4a89b0472edc92c4b87415bedf6b1bbad47ef96721a47473adfc1fd3b59c9
6
+ metadata.gz: 7899e345942d1014a68dccf6a866295a2afafefabc80d4a2abc439a15ab4f6bb35d7ab708f3ef4eb7b548602902b66c850d015fae56b3b4efdc7ab3c4dca5781
7
+ data.tar.gz: 58a8e1db7ae6b58d0e3e0611c4e4b6346e3871ee5556f3f01018d812eb2027703d2bfa3733f63c346304cfbd322b68ec316c8ecb031dfdb356be8a3075a9157a
data/README.md CHANGED
@@ -1,4 +1,10 @@
1
- ### Usage
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 MyApi --spec swagger.json
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 getPetById(petId, params, options = {})
28
- self.class.get("/pet/#{petId}", params: params.to_json, headers: { 'Content-Type' => 'application/json' }.merge(options))
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, headers: { 'Content-Type' => 'application/json' }.merge(options))
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, headers: { 'Content-Type' => 'application/json' }.merge(options))
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 = MyApi.new
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"].select{|it| it["in"] == "path"}.map{|it| it["name"]}
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 (method == "get")
67
+ return parameters.push("options = {}").join(", ") if method == "get"
84
68
 
85
- parameters.push("body").push("options = {}").join(", ")
86
- end
87
-
88
- def schema_to_typed(schema, memo = {})
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
- <%- if endpoint[:method] == 'get' -%>
15
+ <%- unless endpoint[:has_body] -%>
15
16
  def <%= endpoint[:method_name] %>(<%= endpoint[:parameters_for_method] %>)
16
- self.class.<%= endpoint[:method] %>("<%= endpoint[:path] %>", options)
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[:method] %>("<%= endpoint[:path] %>", { body: body.to_json }.merge(options))
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
- <%- if endpoint[:method] == 'get' -%>
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.2.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