wrappix 0.1.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 +7 -0
- data/.rubocop.yml +8 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +216 -0
- data/Rakefile +12 -0
- data/bin/wrappix +7 -0
- data/lib/wrappix/builder.rb +207 -0
- data/lib/wrappix/cli.rb +24 -0
- data/lib/wrappix/client.rb +39 -0
- data/lib/wrappix/configuration.rb +25 -0
- data/lib/wrappix/request.rb +74 -0
- data/lib/wrappix/templates/cache.rb +62 -0
- data/lib/wrappix/templates/client.rb +35 -0
- data/lib/wrappix/templates/collection.rb +32 -0
- data/lib/wrappix/templates/configuration.rb +67 -0
- data/lib/wrappix/templates/documentation.rb +241 -0
- data/lib/wrappix/templates/error.rb +25 -0
- data/lib/wrappix/templates/main.rb +52 -0
- data/lib/wrappix/templates/object.rb +33 -0
- data/lib/wrappix/templates/readme.rb +258 -0
- data/lib/wrappix/templates/request.rb +129 -0
- data/lib/wrappix/templates/resource.rb +115 -0
- data/lib/wrappix/templates/tests.rb +368 -0
- data/lib/wrappix/version.rb +5 -0
- data/lib/wrappix.rb +29 -0
- data/sig/wrappix.rbs +4 -0
- metadata +150 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wrappix
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :base_url, :headers, :timeout
|
6
|
+
attr_reader :resources
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@base_url = nil
|
10
|
+
@headers = {}
|
11
|
+
@timeout = 30
|
12
|
+
@resources = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_resource(name, options = {})
|
16
|
+
@resources[name.to_sym] = options
|
17
|
+
end
|
18
|
+
|
19
|
+
def resources=(resource_hash)
|
20
|
+
resource_hash.each do |name, options|
|
21
|
+
add_resource(name, options)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wrappix
|
4
|
+
class Request
|
5
|
+
def initialize(url, config = Wrappix.configuration)
|
6
|
+
@url = url
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
def get(params: {}, headers: {})
|
11
|
+
handle_response connection.get(@url, params, headers)
|
12
|
+
end
|
13
|
+
|
14
|
+
def post(body: {}, headers: {})
|
15
|
+
handle_response connection.post(@url, body, headers)
|
16
|
+
end
|
17
|
+
|
18
|
+
def patch(body: {}, headers: {})
|
19
|
+
handle_response connection.patch(@url, body, headers)
|
20
|
+
end
|
21
|
+
|
22
|
+
def put(body: {}, headers: {})
|
23
|
+
handle_response connection.put(@url, body, headers)
|
24
|
+
end
|
25
|
+
|
26
|
+
def delete(params: {}, headers: {})
|
27
|
+
handle_response connection.delete(@url, params, headers)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def connection
|
33
|
+
@connection ||= Faraday.new do |conn|
|
34
|
+
conn.url_prefix = @config.base_url
|
35
|
+
|
36
|
+
# Configurar autenticación según el tipo
|
37
|
+
case @config.auth_type
|
38
|
+
when :oauth
|
39
|
+
conn.request :authorization, :Bearer, @config.access_token
|
40
|
+
when :basic
|
41
|
+
conn.basic_auth(@config.username, @config.password)
|
42
|
+
when :api_key
|
43
|
+
conn.headers[@config.api_key_header] = @config.api_key
|
44
|
+
end
|
45
|
+
|
46
|
+
conn.request :json
|
47
|
+
conn.response :json, content_type: "application/json", parser_options: { symbolize_names: true }
|
48
|
+
conn.adapter Faraday.default_adapter
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def handle_response(response)
|
53
|
+
return response if response.status.between?(200, 299)
|
54
|
+
|
55
|
+
error_message = if response.body.is_a?(Hash)
|
56
|
+
response.body[:message] || response.body[:error] || "Error #{response.status}"
|
57
|
+
else
|
58
|
+
"Error #{response.status}"
|
59
|
+
end
|
60
|
+
|
61
|
+
raise Wrappix::Error.new(error_message, response.body, response.status)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Error < StandardError
|
66
|
+
attr_reader :body, :status
|
67
|
+
|
68
|
+
def initialize(message, body = nil, status = nil)
|
69
|
+
@body = body
|
70
|
+
@status = status
|
71
|
+
super(message)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wrappix
|
4
|
+
module Templates
|
5
|
+
class Cache
|
6
|
+
def self.render(module_name, _config)
|
7
|
+
<<~RUBY
|
8
|
+
# frozen_string_literal: true
|
9
|
+
|
10
|
+
module #{module_name}
|
11
|
+
# Memory cache implementation
|
12
|
+
class MemoryCache
|
13
|
+
def initialize
|
14
|
+
@store = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def read(key)
|
18
|
+
@store[key]
|
19
|
+
end
|
20
|
+
|
21
|
+
def write(key, value)
|
22
|
+
@store[key] = value
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete(key)
|
26
|
+
@store.delete(key)
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear
|
30
|
+
@store = {}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# File cache implementation
|
35
|
+
class FileCache
|
36
|
+
def initialize(path = "#{module_name.downcase}_cache.yaml")
|
37
|
+
require "yaml/store"
|
38
|
+
@store = YAML::Store.new(path)
|
39
|
+
end
|
40
|
+
|
41
|
+
def read(key)
|
42
|
+
@store.transaction(true) { @store[key] }
|
43
|
+
end
|
44
|
+
|
45
|
+
def write(key, value)
|
46
|
+
@store.transaction { @store[key] = value }
|
47
|
+
end
|
48
|
+
|
49
|
+
def delete(key)
|
50
|
+
@store.transaction { @store.delete(key) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def clear
|
54
|
+
@store.transaction { @store.roots.each { |key| @store.delete(key) } }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
RUBY
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wrappix
|
4
|
+
module Templates
|
5
|
+
class Client
|
6
|
+
def self.render(module_name, config)
|
7
|
+
<<~RUBY
|
8
|
+
# frozen_string_literal: true
|
9
|
+
|
10
|
+
module #{module_name}
|
11
|
+
class Client
|
12
|
+
def initialize(configuration = #{module_name}.configuration)
|
13
|
+
@configuration = configuration
|
14
|
+
end
|
15
|
+
|
16
|
+
#{resource_methods(module_name, config)}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
RUBY
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.resource_methods(_module_name, config)
|
23
|
+
resources = config["resources"] || {}
|
24
|
+
|
25
|
+
resources.map do |name, _config|
|
26
|
+
<<~RUBY.strip
|
27
|
+
def #{name}
|
28
|
+
@#{name} ||= Resources::#{name.capitalize}.new(self)
|
29
|
+
end
|
30
|
+
RUBY
|
31
|
+
end.join("\n\n")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# lib/wrappix/templates/collection.rb
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Wrappix
|
5
|
+
module Templates
|
6
|
+
class Collection
|
7
|
+
def self.render(module_name, _config)
|
8
|
+
<<~RUBY
|
9
|
+
# frozen_string_literal: true
|
10
|
+
|
11
|
+
module #{module_name}
|
12
|
+
class Collection
|
13
|
+
attr_reader :data, :next_href
|
14
|
+
|
15
|
+
def self.from_response(response_body, type:)
|
16
|
+
new(
|
17
|
+
data: response_body[:data]&.map { |attrs| type.new(attrs) },
|
18
|
+
next_href: response_body[:next_href]
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(data:, next_href:)
|
23
|
+
@data = data
|
24
|
+
@next_href = next_href
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
RUBY
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wrappix
|
4
|
+
module Templates
|
5
|
+
class Configuration
|
6
|
+
def self.render(module_name, config)
|
7
|
+
<<~RUBY
|
8
|
+
# frozen_string_literal: true
|
9
|
+
|
10
|
+
module #{module_name}
|
11
|
+
class Configuration
|
12
|
+
attr_accessor :base_url, :timeout, :headers
|
13
|
+
#{auth_config_attributes(config)}
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@base_url = "#{config["base_url"] || "https://api.example.com"}"
|
17
|
+
@timeout = 30
|
18
|
+
@headers = {
|
19
|
+
"Content-Type" => "application/json",
|
20
|
+
"Accept" => "application/json"
|
21
|
+
}
|
22
|
+
#{auth_config_initialization(config)}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
RUBY
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.auth_config_attributes(config)
|
30
|
+
case config["auth_type"]
|
31
|
+
when "oauth"
|
32
|
+
"attr_accessor :client_id, :client_secret, :token_url, :access_token"
|
33
|
+
when "basic"
|
34
|
+
"attr_accessor :username, :password"
|
35
|
+
when "api_key"
|
36
|
+
"attr_accessor :api_key, :api_key_header"
|
37
|
+
else
|
38
|
+
""
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.auth_config_initialization(config)
|
43
|
+
case config["auth_type"]
|
44
|
+
when "oauth"
|
45
|
+
<<~RUBY.strip
|
46
|
+
@client_id = nil
|
47
|
+
@client_secret = nil
|
48
|
+
@token_url = "#{config["token_url"] || "https://api.example.com/oauth/token"}"
|
49
|
+
@access_token = nil
|
50
|
+
RUBY
|
51
|
+
when "basic"
|
52
|
+
<<~RUBY.strip
|
53
|
+
@username = nil
|
54
|
+
@password = nil
|
55
|
+
RUBY
|
56
|
+
when "api_key"
|
57
|
+
<<~RUBY.strip
|
58
|
+
@api_key = nil
|
59
|
+
@api_key_header = "#{config["api_key_header"] || "X-Api-Key"}"
|
60
|
+
RUBY
|
61
|
+
else
|
62
|
+
""
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,241 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wrappix
|
4
|
+
module Templates
|
5
|
+
class Documentation
|
6
|
+
def self.render(_api_name, module_name, config)
|
7
|
+
base_url = config["base_url"] || "https://api.example.com"
|
8
|
+
resources = config["resources"] || {}
|
9
|
+
|
10
|
+
# Cabecera y descripción general
|
11
|
+
doc = <<~MARKDOWN
|
12
|
+
# #{module_name} API Documentation
|
13
|
+
|
14
|
+
This document provides detailed information about the endpoints available in the #{module_name} API client.
|
15
|
+
|
16
|
+
**API Base URL:** `#{base_url}`
|
17
|
+
|
18
|
+
## Table of Contents
|
19
|
+
|
20
|
+
- [Authentication](#authentication)
|
21
|
+
#{resources.keys.map { |r| "- [#{r.capitalize}](##{r})" }.join("\n ")}
|
22
|
+
|
23
|
+
## Authentication
|
24
|
+
|
25
|
+
#{render_authentication_docs(config)}
|
26
|
+
|
27
|
+
## Resources
|
28
|
+
|
29
|
+
MARKDOWN
|
30
|
+
|
31
|
+
# Añadir documentación para cada recurso
|
32
|
+
resources.each do |resource_name, resource_config|
|
33
|
+
doc += render_resource_docs(resource_name, resource_config, module_name, base_url)
|
34
|
+
end
|
35
|
+
|
36
|
+
doc
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.render_authentication_docs(config)
|
40
|
+
case config["auth_type"]
|
41
|
+
when "oauth"
|
42
|
+
<<~MARKDOWN
|
43
|
+
This API uses OAuth 2.0 authentication. You need to obtain an access token from the authorization server.
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
#{config["api_name"].gsub("-", "_").capitalize}.configure do |config|
|
47
|
+
config.client_id = "YOUR_CLIENT_ID"
|
48
|
+
config.client_secret = "YOUR_CLIENT_SECRET"
|
49
|
+
end
|
50
|
+
```
|
51
|
+
MARKDOWN
|
52
|
+
when "basic"
|
53
|
+
<<~MARKDOWN
|
54
|
+
This API uses HTTP Basic Authentication.
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
#{config["api_name"].gsub("-", "_").capitalize}.configure do |config|
|
58
|
+
config.username = "YOUR_USERNAME"
|
59
|
+
config.password = "YOUR_PASSWORD"
|
60
|
+
end
|
61
|
+
```
|
62
|
+
MARKDOWN
|
63
|
+
when "api_key"
|
64
|
+
header = config["api_key_header"] || "X-Api-Key"
|
65
|
+
<<~MARKDOWN
|
66
|
+
This API uses API Key authentication. The key should be provided in the `#{header}` header.
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
#{config["api_name"].gsub("-", "_").capitalize}.configure do |config|
|
70
|
+
config.api_key = "YOUR_API_KEY"
|
71
|
+
end
|
72
|
+
```
|
73
|
+
MARKDOWN
|
74
|
+
else
|
75
|
+
"This API does not require authentication."
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.render_resource_docs(resource_name, resource_config, module_name, base_url)
|
80
|
+
endpoints = resource_config["endpoints"] || []
|
81
|
+
singular_name = resource_name.end_with?("s") ? resource_name.chop : resource_name
|
82
|
+
|
83
|
+
doc = <<~MARKDOWN
|
84
|
+
|
85
|
+
<a name="#{resource_name}"></a>
|
86
|
+
## #{resource_name.capitalize}
|
87
|
+
|
88
|
+
MARKDOWN
|
89
|
+
|
90
|
+
endpoints.each do |endpoint|
|
91
|
+
doc += render_endpoint_docs(endpoint, resource_name, singular_name, module_name, base_url)
|
92
|
+
end
|
93
|
+
|
94
|
+
doc
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.render_endpoint_docs(endpoint, resource_name, singular_name, _module_name, base_url)
|
98
|
+
name = endpoint["name"]
|
99
|
+
method = endpoint["method"]&.upcase || "GET"
|
100
|
+
path = endpoint["path"] || name
|
101
|
+
|
102
|
+
# Extraer los parámetros del path
|
103
|
+
path_params = path.scan(/\{([^}]+)\}/).flatten
|
104
|
+
|
105
|
+
# Generar la URL completa para la documentación
|
106
|
+
full_url = "#{base_url.chomp("/")}/#{path}"
|
107
|
+
|
108
|
+
# Generar la llamada al método para la documentación
|
109
|
+
method_params = []
|
110
|
+
method_params.concat(path_params)
|
111
|
+
method_params << "params" if endpoint["params"]
|
112
|
+
method_params << "body" if %w[POST PUT PATCH].include?(method)
|
113
|
+
|
114
|
+
client_call = "client.#{resource_name}.#{name}(#{method_params.join(", ")})"
|
115
|
+
|
116
|
+
# Documentación del endpoint
|
117
|
+
doc = <<~MARKDOWN
|
118
|
+
|
119
|
+
### #{name}
|
120
|
+
|
121
|
+
**#{method}** `#{full_url}`
|
122
|
+
|
123
|
+
#{endpoint["description"] || "No description provided."}
|
124
|
+
|
125
|
+
#### Parameters
|
126
|
+
MARKDOWN
|
127
|
+
|
128
|
+
# Añadir documentación de parámetros
|
129
|
+
if path_params.empty? && !endpoint["params"] && !%w[POST PUT PATCH].include?(method)
|
130
|
+
doc += "\nThis endpoint does not require any parameters.\n"
|
131
|
+
else
|
132
|
+
if path_params.any?
|
133
|
+
doc += "\n**Path Parameters:**\n\n"
|
134
|
+
path_params.each do |param|
|
135
|
+
doc += "- `#{param}`: Required. #{param_description(param)}\n"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
if endpoint["params"]
|
140
|
+
doc += "\n**Query Parameters:**\n\n"
|
141
|
+
doc += "- This endpoint accepts additional query parameters.\n"
|
142
|
+
end
|
143
|
+
|
144
|
+
if %w[POST PUT PATCH].include?(method)
|
145
|
+
doc += "\n**Request Body:**\n\n"
|
146
|
+
doc += "- This endpoint accepts a request body with the resource attributes.\n"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# Añadir ejemplos de uso
|
151
|
+
doc += <<~MARKDOWN
|
152
|
+
|
153
|
+
#### Example Usage
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
#{client_call}
|
157
|
+
```
|
158
|
+
|
159
|
+
#### Response
|
160
|
+
|
161
|
+
#{response_example(name, singular_name, endpoint["collection"])}
|
162
|
+
MARKDOWN
|
163
|
+
|
164
|
+
doc
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.param_description(param)
|
168
|
+
case param
|
169
|
+
when "id"
|
170
|
+
"The unique identifier of the resource."
|
171
|
+
when "customer_id"
|
172
|
+
"The identifier of the customer."
|
173
|
+
when /^(\w+)_id$/
|
174
|
+
"The identifier of the #{::Regexp.last_match(1)}."
|
175
|
+
else
|
176
|
+
"Description not available."
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def self.response_example(name, resource_name, _is_collection)
|
181
|
+
case name
|
182
|
+
when "list", "all", "index", "search"
|
183
|
+
<<~MARKDOWN
|
184
|
+
```ruby
|
185
|
+
# Returns a Collection object
|
186
|
+
collection.data.each do |#{resource_name}|
|
187
|
+
puts #{resource_name}.id
|
188
|
+
puts #{resource_name}.name
|
189
|
+
# Other attributes...
|
190
|
+
end
|
191
|
+
|
192
|
+
# Pagination information
|
193
|
+
puts collection.next_href # URL for the next page, if available
|
194
|
+
```
|
195
|
+
MARKDOWN
|
196
|
+
when "get", "find", "show"
|
197
|
+
<<~MARKDOWN
|
198
|
+
```ruby
|
199
|
+
# Returns a single Object
|
200
|
+
puts #{resource_name}.id
|
201
|
+
puts #{resource_name}.name
|
202
|
+
# Other attributes...
|
203
|
+
```
|
204
|
+
MARKDOWN
|
205
|
+
when "create"
|
206
|
+
<<~MARKDOWN
|
207
|
+
```ruby
|
208
|
+
# Returns the created object
|
209
|
+
puts #{resource_name}.id
|
210
|
+
puts #{resource_name}.created_at
|
211
|
+
# Other attributes...
|
212
|
+
```
|
213
|
+
MARKDOWN
|
214
|
+
when "update"
|
215
|
+
<<~MARKDOWN
|
216
|
+
```ruby
|
217
|
+
# Returns the updated object
|
218
|
+
puts #{resource_name}.id
|
219
|
+
puts #{resource_name}.updated_at
|
220
|
+
# Other attributes...
|
221
|
+
```
|
222
|
+
MARKDOWN
|
223
|
+
when "delete", "destroy", "remove"
|
224
|
+
<<~MARKDOWN
|
225
|
+
```ruby
|
226
|
+
# Returns a success indicator or the deleted object
|
227
|
+
puts "Resource deleted successfully"
|
228
|
+
```
|
229
|
+
MARKDOWN
|
230
|
+
else
|
231
|
+
<<~MARKDOWN
|
232
|
+
```ruby
|
233
|
+
# Returns a response specific to this endpoint
|
234
|
+
puts response # Examine the response structure
|
235
|
+
```
|
236
|
+
MARKDOWN
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wrappix
|
4
|
+
module Templates
|
5
|
+
class Error
|
6
|
+
def self.render(module_name, _config)
|
7
|
+
<<~RUBY
|
8
|
+
# frozen_string_literal: true
|
9
|
+
|
10
|
+
module #{module_name}
|
11
|
+
class Error < StandardError
|
12
|
+
attr_reader :body, :status
|
13
|
+
|
14
|
+
def initialize(message, body = nil, status = nil)
|
15
|
+
@body = body
|
16
|
+
@status = status
|
17
|
+
super(message)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
RUBY
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wrappix
|
4
|
+
module Templates
|
5
|
+
class Main
|
6
|
+
def self.render(api_name, module_name, config)
|
7
|
+
# api_name ya debería estar normalizado aquí
|
8
|
+
resources = config["resources"] || {}
|
9
|
+
resource_requires = resources.keys.map do |r|
|
10
|
+
"require_relative \"#{api_name}/resources/#{r}\""
|
11
|
+
end.join("\n")
|
12
|
+
|
13
|
+
<<~RUBY
|
14
|
+
# frozen_string_literal: true
|
15
|
+
|
16
|
+
require_relative "#{api_name}/version"
|
17
|
+
require_relative "#{api_name}/configuration"
|
18
|
+
require_relative "#{api_name}/error"
|
19
|
+
require_relative "#{api_name}/request"
|
20
|
+
require_relative "#{api_name}/object"
|
21
|
+
require_relative "#{api_name}/collection"
|
22
|
+
require_relative "#{api_name}/client"
|
23
|
+
require_relative "#{api_name}/cache"
|
24
|
+
|
25
|
+
# Resources
|
26
|
+
#{resource_requires}
|
27
|
+
|
28
|
+
module #{module_name}
|
29
|
+
class << self
|
30
|
+
attr_accessor :configuration, :cache
|
31
|
+
|
32
|
+
def configure
|
33
|
+
self.configuration ||= Configuration.new
|
34
|
+
yield(configuration) if block_given?
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
# Método para acceder al cliente
|
39
|
+
def client
|
40
|
+
@client ||= Client.new(configuration)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Default to memory cache
|
45
|
+
self.cache = MemoryCache.new
|
46
|
+
self.configuration = Configuration.new
|
47
|
+
end
|
48
|
+
RUBY
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wrappix
|
4
|
+
module Templates
|
5
|
+
class Object
|
6
|
+
def self.render(module_name, _config)
|
7
|
+
<<~RUBY
|
8
|
+
# frozen_string_literal: true
|
9
|
+
|
10
|
+
require "ostruct"
|
11
|
+
|
12
|
+
module #{module_name}
|
13
|
+
class Object < OpenStruct
|
14
|
+
def initialize(attributes)
|
15
|
+
super(to_ostruct(attributes))
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_ostruct(obj)
|
19
|
+
if obj.is_a?(Hash)
|
20
|
+
OpenStruct.new(obj.transform_values { |val| to_ostruct(val) })
|
21
|
+
elsif obj.is_a?(Array)
|
22
|
+
obj.map { |o| to_ostruct(o) }
|
23
|
+
else
|
24
|
+
obj
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
RUBY
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|