swagger-to-rbs 0.5.0 → 1.0.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: ddb76510d5a4e87aee8bb582481a21c80616fa83e58a6fc49e8c1b02e449a4a5
4
- data.tar.gz: 3460975741e8aad8d93e42939ef77cd6b40ba63ac3febf946e8a3e0af388618d
3
+ metadata.gz: 4009216d856b770d4226cdc662c17250a113cf2a06366f7a5731d39a72d417ed
4
+ data.tar.gz: 456756e34e5ce92d602ac0c23aa0d6e243a78b95e4f20a39210976a477a41ad7
5
5
  SHA512:
6
- metadata.gz: 1c788888a133f558bfae8348f7d22012e401ce42f6cdac5ed5248b7a669e5dbde5b797145316a626a39a2fff667f283ec6d0b5f75e2d663f6e004540f804c7b6
7
- data.tar.gz: ba69ff9e2377795ed266c9319254d94695d758d5795ff64d26fe81996f01ef595567b75787d413dcb8bf6177bb699fc09c1f408c4dd8d5bc2cc85c9a6142af45
6
+ metadata.gz: ba0e9c1101cfa113600e891feef046f2aff46b4dfa56d8c9f16dc38f08327ecd5bc16f49633bbb5420a7835401ceb0c3cd036137eccd7e7636da3537fb9fd866
7
+ data.tar.gz: 1b374d837cf5050238dac0096866624da70c192e7d03dca63f425cca3f44619f2020cedd441584dd8cc56582829753358c00fc723ee6d8e9f826762611415843
@@ -1,6 +1,24 @@
1
1
  module Swagger2Rbs
2
2
  class HashHelper
3
3
 
4
+ def self.resolve_special_key(data, special_key)
5
+ return data unless data
6
+
7
+ new_data = data.dup
8
+ walk(data) do |key, value|
9
+ if (key.split(".").last == special_key)
10
+ update_key = key.split(".").reject{|k| k == special_key}.join(".")
11
+ new_value = yield(key, value)
12
+ set_value(new_data, update_key, new_value)
13
+ end
14
+ end
15
+ new_data
16
+ end
17
+
18
+ def self.present?(hash)
19
+ hash && !hash.empty?
20
+ end
21
+
4
22
  # https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/hash/keys.rb#L129
5
23
  def self.deep_transform_keys_in_object!(object, &block)
6
24
  case object
@@ -0,0 +1,46 @@
1
+ module Swagger2Rbs
2
+ class RbsType
3
+ attr_reader :data, :symbolize_keys
4
+ def initialize(data, symbolize_keys: true)
5
+ @data = data
6
+ @symbolize_keys = symbolize_keys
7
+ end
8
+
9
+ def write_types
10
+ return nil unless HashHelper.present? data
11
+ typed = (data.is_a?(Array) ? data[0] : data)&.map{ |k, v| to_typed(k, v) }.join(', ')
12
+ if data.is_a?(Array)
13
+ "Array[{ #{typed} }]"
14
+ else
15
+ "{ #{typed} }"
16
+ end
17
+ end
18
+
19
+ def type_case(str)
20
+ case str
21
+ when "boolean"
22
+ "bool"
23
+ when nil
24
+ "untyped"
25
+ else
26
+ str&.capitalize
27
+ end
28
+ end
29
+
30
+ def key_to_typed(k)
31
+ return "#{k}:" if @symbolize_keys
32
+ "\"#{k}\" =>"
33
+ end
34
+
35
+ def to_typed(k, v)
36
+ return "#{key_to_typed(k)} #{type_case(v)}" unless v.is_a?(Array) || v.is_a?(Hash)
37
+ return "#{key_to_typed(k)} {#{v.map{ |k2, v2| to_typed(k2, v2) }.join(", ")}}" if v.is_a?(Hash)
38
+
39
+ if v[0]&.is_a?(Hash)
40
+ "#{key_to_typed(k)} Array[{" + v[0].map{ |k, v| to_typed(k, v) }.join(", ") + "}]"
41
+ else
42
+ "#{key_to_typed(k)} Array[#{type_case(v[0])}]"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -20,14 +20,15 @@ module Swagger2Rbs
20
20
  typed_parameters_for_method: typed_parameters_for_method,
21
21
  has_body: body?,
22
22
  method_name: method_name,
23
- response_typed: response_typed,
23
+ all_responses_typed: all_responses_typed,
24
+ all_responses_for_return_method: all_responses_for_return_method,
24
25
  }
25
26
  rescue => e
26
27
  raise e, "Context: #{path} #{method} Message: #{e.message}"
27
28
  end
28
29
 
29
30
  def body?
30
- body && !body.empty?
31
+ HashHelper.present? body
31
32
  end
32
33
 
33
34
  def to_yaml
@@ -37,7 +38,8 @@ module Swagger2Rbs
37
38
  path_parameters: parameters,
38
39
  method_name: method_name,
39
40
  body: body,
40
- response: response_typed,
41
+ response: response("200"),
42
+ all_responses: all_responses
41
43
  }
42
44
  rescue => e
43
45
  raise e, "Context: #{path} #{method} Message: #{e.message}"
@@ -61,7 +63,25 @@ module Swagger2Rbs
61
63
  body_schema = resolve_of(props.dig("requestBody", "content", "application/json", "schema"))
62
64
  return {} unless body_schema
63
65
 
64
- schema_to_typed(body_schema)
66
+ schema_to_hash(body_schema)
67
+ end
68
+
69
+ def response(http_code)
70
+ schema = resolve_all_of(@props.dig("responses", http_code, "content", "application/json", "schema"))
71
+ schema_to_hash(schema, {})
72
+ end
73
+
74
+ def all_responses
75
+ result = @props.dig("responses").keys.reduce({}) do |memo, key|
76
+ memo.merge({ key => response(key) })
77
+ end
78
+ end
79
+
80
+ def all_responses_for_return_method
81
+ return '{ "200" => response }' if all_responses.empty?
82
+
83
+ result = all_responses.keys.map{|key| "\"#{key}\" => response" }.join(", ")
84
+ "{ #{result} }"
65
85
  end
66
86
 
67
87
  def parameters_for_method
@@ -74,6 +94,29 @@ module Swagger2Rbs
74
94
  end
75
95
  end
76
96
 
97
+ def schema_to_hash(schema, memo = {})
98
+ return nil unless schema
99
+
100
+ properties = schema["type"] == "array" ? schema["items"]["properties"] : schema["properties"]
101
+
102
+ result = properties&.reduce(memo)do |memo, (k,v)|
103
+ if v["type"] == "object"
104
+ memo.merge({k => schema_to_hash(v, {})})
105
+ elsif v["type"] == "array"
106
+ if v.dig("items", "type") == "object"
107
+ memo.merge({k => [schema_to_hash(v["items"], {})] })
108
+ else
109
+ memo.merge({k => [v.dig("items", "type")] })
110
+ end
111
+ else
112
+ memo.merge({k => v["type"] })
113
+ end
114
+ end
115
+ return [result] if schema["type"] == "array"
116
+
117
+ result
118
+ end
119
+
77
120
  def resolve_of(data)
78
121
  resolve_all_of(resolve_one_of(data))
79
122
  end
@@ -86,10 +129,12 @@ module Swagger2Rbs
86
129
  end
87
130
 
88
131
  def resolve_all_of(data)
89
- return data unless data
90
- return data unless data["allOf"]
91
-
92
- data["allOf"].reduce(&:merge)
132
+ HashHelper.resolve_special_key(data, "allOf") do |key, value|
133
+ value.reduce(value[0]) do |memo, it|
134
+ memo["properties"] = memo["properties"].merge(it["properties"])
135
+ memo
136
+ end
137
+ end
93
138
  end
94
139
  end
95
140
  end
@@ -1,11 +1,6 @@
1
+ require_relative './rbs_type'
1
2
  module Swagger2Rbs
2
-
3
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
4
  def typed_parameters_for_method
10
5
  options_typed = "?Hash[untyped, untyped] options"
11
6
  return "(#{options_typed})" unless body && parameters
@@ -19,56 +14,17 @@ module Swagger2Rbs
19
14
  end
20
15
 
21
16
  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
17
+ RbsType.new(body).write_types
38
18
  end
39
19
 
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
20
+ def response_typed(http_code)
21
+ RbsType.new(response(http_code), symbolize_keys: false).write_types
49
22
  end
50
23
 
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"]
24
+ def all_responses_typed
25
+ return '{ "200" => untyped }' unless @props.dig("responses")
70
26
 
71
- result
27
+ RbsType.new(all_responses, symbolize_keys: false).write_types
72
28
  end
73
29
  end
74
30
  end
data/lib/swagger2_rbs.rb CHANGED
@@ -5,23 +5,11 @@ require_relative 'swagger2_rbs/hash_helper'
5
5
 
6
6
  module Swagger2Rbs
7
7
 
8
- def self.resolve_ref(hash, key, value)
9
- ref_key = value.gsub("#/", "").split("/")
10
- data = hash.dig(*ref_key)
11
- update_key = key.split(".").reject{|k| k == "$ref"}.join(".")
12
-
13
- [update_key, data]
14
- end
15
-
16
8
  def self.resolve_all_ref(swagger_spec)
17
- new_swagger_spec = swagger_spec.dup
18
- HashHelper.walk(swagger_spec) do |key, value|
19
- if key.split(".").last == "$ref"
20
- update_key, data = resolve_ref(swagger_spec, key, value)
21
- HashHelper.set_value(new_swagger_spec, update_key, data)
22
- end
9
+ HashHelper.resolve_special_key(swagger_spec, "$ref") do |key, value|
10
+ ref_key = value.gsub("#/", "").split("/")
11
+ swagger_spec.dig(*ref_key)
23
12
  end
24
- new_swagger_spec
25
13
  end
26
14
 
27
15
  def self.swagger_to_rest_api(swagger_spec, parse_method = :to_h)
@@ -13,11 +13,13 @@ class <%= @module_name %>
13
13
 
14
14
  <%- unless endpoint[:has_body] -%>
15
15
  def <%= endpoint[:method_name] %>(<%= endpoint[:parameters_for_method] %>)
16
- self.class.<%= endpoint[:http_method] %>("<%= endpoint[:path] %>", options)
16
+ response = self.class.<%= endpoint[:http_method] %>("<%= endpoint[:path] %>", options)
17
+ [response, <%= endpoint[:all_responses_for_return_method] %>]
17
18
  end
18
19
  <%- else -%>
19
20
  def <%= endpoint[:method_name] %>(<%= endpoint[:parameters_for_method] %>)
20
- self.class.<%= endpoint[:http_method] %>("<%= endpoint[:path] %>", { body: body.to_json }.merge(options))
21
+ response = self.class.<%= endpoint[:http_method] %>("<%= endpoint[:path] %>", { body: body.to_json }.merge(options))
22
+ [response, <%= endpoint[:all_responses_for_return_method] %>]
21
23
  end
22
24
  <%- end -%>
23
25
  <%- end -%>
@@ -4,6 +4,7 @@ module HTTParty
4
4
  class Response
5
5
  def body: -> untyped
6
6
  def success?: -> bool
7
+ def code: -> Integer
7
8
  end
8
9
  end
9
10
 
@@ -12,14 +13,14 @@ class <%= @module_name %>
12
13
 
13
14
  def self.headers: (untyped headers) -> void
14
15
  def self.base_uri: (String uri) -> void
15
- def self.get: (String path, untyped options) -> void
16
- def self.post: (String path, untyped options) -> void
17
- def self.put: (String path, untyped options) -> void
18
- def self.delete: (String path, untyped options) -> void
16
+ def self.get: (String path, untyped options) -> HTTParty::Response
17
+ def self.post: (String path, untyped options) -> HTTParty::Response
18
+ def self.put: (String path, untyped options) -> HTTParty::Response
19
+ def self.delete: (String path, untyped options) -> HTTParty::Response
19
20
 
20
21
  def initialize: -> void
21
22
  <%- @data[:endpoints].each do |endpoint| -%>
22
23
 
23
- def <%= endpoint[:method_name] %>: <%= endpoint[:typed_parameters_for_method] %> -> HTTParty::Response
24
+ def <%= endpoint[:method_name] %>: <%= endpoint[:typed_parameters_for_method] %> -> [HTTParty::Response, <%= endpoint[:all_responses_typed] %>]
24
25
  <%- end -%>
25
26
  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.5.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Savignano
@@ -51,6 +51,7 @@ files:
51
51
  - lib/swagger2_rbs.rb
52
52
  - lib/swagger2_rbs/cli.rb
53
53
  - lib/swagger2_rbs/hash_helper.rb
54
+ - lib/swagger2_rbs/rbs_type.rb
54
55
  - lib/swagger2_rbs/rest_endpoint.rb
55
56
  - lib/swagger2_rbs/rest_endpoint_typed.rb
56
57
  - lib/templates/http_client.rb.erb