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,368 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wrappix
|
4
|
+
module Templates
|
5
|
+
class Tests
|
6
|
+
def self.render(_api_name, module_name, config)
|
7
|
+
resources = config["resources"] || {}
|
8
|
+
|
9
|
+
test_content = <<~RUBY
|
10
|
+
# frozen_string_literal: true
|
11
|
+
|
12
|
+
require "test_helper"
|
13
|
+
|
14
|
+
class #{module_name}Test < Minitest::Test
|
15
|
+
def setup
|
16
|
+
# Reset configuration before each test
|
17
|
+
#{module_name}.configuration = #{module_name}::Configuration.new
|
18
|
+
|
19
|
+
# Configure base settings
|
20
|
+
#{module_name}.configure do |config|
|
21
|
+
config.base_url = "#{config["base_url"] || "https://api.example.com"}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def teardown
|
26
|
+
# No need to restore anything
|
27
|
+
end
|
28
|
+
|
29
|
+
#{config_tests(module_name, config)}
|
30
|
+
|
31
|
+
#{client_tests(module_name, resources.keys)}
|
32
|
+
|
33
|
+
#{error_tests(module_name)}
|
34
|
+
end
|
35
|
+
RUBY
|
36
|
+
|
37
|
+
# Generar tests de recursos en archivos separados
|
38
|
+
resources.each do |resource_name, resource_config|
|
39
|
+
resource_test(module_name, resource_name, resource_config, config)
|
40
|
+
# Aquí podrías devolver o guardar estos tests en archivos separados
|
41
|
+
end
|
42
|
+
|
43
|
+
test_content
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.config_tests(module_name, config)
|
47
|
+
auth_config = case config["auth_type"]
|
48
|
+
when "oauth"
|
49
|
+
<<~RUBY.strip
|
50
|
+
config.client_id = "test_client_id"
|
51
|
+
config.client_secret = "test_client_secret"
|
52
|
+
config.token_url = "#{config["token_url"] || "https://api.example.com/oauth/token"}"
|
53
|
+
RUBY
|
54
|
+
when "basic"
|
55
|
+
<<~RUBY.strip
|
56
|
+
config.username = "test_username"
|
57
|
+
config.password = "test_password"
|
58
|
+
RUBY
|
59
|
+
when "api_key"
|
60
|
+
<<~RUBY.strip
|
61
|
+
config.api_key = "test_api_key"
|
62
|
+
config.api_key_header = "#{config["api_key_header"] || "X-Api-Key"}"
|
63
|
+
RUBY
|
64
|
+
else
|
65
|
+
""
|
66
|
+
end
|
67
|
+
|
68
|
+
<<~RUBY
|
69
|
+
def test_configuration
|
70
|
+
#{module_name}.configure do |config|
|
71
|
+
config.base_url = "https://api.test.org"
|
72
|
+
config.timeout = 60
|
73
|
+
#{auth_config}
|
74
|
+
end
|
75
|
+
|
76
|
+
assert_equal "https://api.test.org", #{module_name}.configuration.base_url
|
77
|
+
assert_equal 60, #{module_name}.configuration.timeout
|
78
|
+
#{verify_auth_config(module_name, config)}
|
79
|
+
end
|
80
|
+
RUBY
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.verify_auth_config(module_name, config)
|
84
|
+
case config["auth_type"]
|
85
|
+
when "oauth"
|
86
|
+
<<~RUBY
|
87
|
+
assert_equal "test_client_id", #{module_name}.configuration.client_id
|
88
|
+
assert_equal "test_client_secret", #{module_name}.configuration.client_secret
|
89
|
+
RUBY
|
90
|
+
when "basic"
|
91
|
+
<<~RUBY
|
92
|
+
assert_equal "test_username", #{module_name}.configuration.username
|
93
|
+
assert_equal "test_password", #{module_name}.configuration.password
|
94
|
+
RUBY
|
95
|
+
when "api_key"
|
96
|
+
<<~RUBY
|
97
|
+
assert_equal "test_api_key", #{module_name}.configuration.api_key
|
98
|
+
RUBY
|
99
|
+
else
|
100
|
+
""
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.client_tests(module_name, resource_names)
|
105
|
+
resource_assertions = resource_names.map do |name|
|
106
|
+
" assert_respond_to client, :#{name}"
|
107
|
+
end.join("\n")
|
108
|
+
|
109
|
+
<<~RUBY
|
110
|
+
def test_client_initialization
|
111
|
+
client = #{module_name}::Client.new
|
112
|
+
|
113
|
+
assert_instance_of #{module_name}::Client, client
|
114
|
+
#{resource_assertions}
|
115
|
+
end
|
116
|
+
RUBY
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.resource_test(module_name, resource_name, resource_config, global_config)
|
120
|
+
endpoints = resource_config["endpoints"] || []
|
121
|
+
|
122
|
+
endpoint_tests = endpoints.map do |endpoint|
|
123
|
+
endpoint_test(module_name, resource_name, endpoint, resource_config, global_config)
|
124
|
+
end.join("\n\n")
|
125
|
+
|
126
|
+
<<~RUBY
|
127
|
+
# Tests for #{resource_name} resource
|
128
|
+
#{endpoint_tests}
|
129
|
+
RUBY
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.endpoint_test(module_name, resource_name, endpoint, resource_config, global_config)
|
133
|
+
name = endpoint["name"]
|
134
|
+
method = endpoint["method"] || "get"
|
135
|
+
path = endpoint["path"] || name
|
136
|
+
|
137
|
+
# Obtener los casos de prueba definidos o crear uno predeterminado
|
138
|
+
test_cases = endpoint["tests"] || [create_default_test_case(endpoint)]
|
139
|
+
|
140
|
+
# Generar un test para cada caso
|
141
|
+
test_cases.map.with_index do |test_case, index|
|
142
|
+
generate_test_method(module_name, resource_name, name, method, path, test_case, index, resource_config,
|
143
|
+
global_config)
|
144
|
+
end.join("\n\n")
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.create_default_test_case(endpoint)
|
148
|
+
name = endpoint["name"]
|
149
|
+
path = endpoint["path"] || name
|
150
|
+
is_collection = endpoint["collection"] || %w[all list index search].include?(name)
|
151
|
+
|
152
|
+
# Obtener los parámetros del path
|
153
|
+
path_params = path.scan(/\{([^}]+)\}/).flatten
|
154
|
+
path_params_values = path_params.map { |p| [p, "123"] }.to_h
|
155
|
+
|
156
|
+
# Crear un caso de prueba predeterminado
|
157
|
+
{
|
158
|
+
"description" => "funciona correctamente",
|
159
|
+
"request" => {
|
160
|
+
"path_params" => path_params_values,
|
161
|
+
"params" => endpoint["params"] ? { "page" => 1 } : {},
|
162
|
+
"body" => %w[post put patch].include?(endpoint["method"].to_s) ? { "name" => "Test" } : {}
|
163
|
+
},
|
164
|
+
"response" => {
|
165
|
+
"status" => 200,
|
166
|
+
"body" => if is_collection
|
167
|
+
{ "data" => [{ "id" => 1, "name" => "Test" }], "next_href" => "/next" }
|
168
|
+
else
|
169
|
+
{ "id" => 1, "name" => "Test" }
|
170
|
+
end
|
171
|
+
}
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
def self.generate_test_method(module_name, resource_name, endpoint_name, method, path, test_case, index, resource_config, global_config)
|
176
|
+
description = test_case["description"] || "case #{index + 1}"
|
177
|
+
# Normalizar la descripción para el nombre del método
|
178
|
+
method_name_desc = description.downcase.gsub(/[^a-z0-9]/, "_")
|
179
|
+
|
180
|
+
request = test_case["request"] || {}
|
181
|
+
response = test_case["response"] || {}
|
182
|
+
|
183
|
+
# Preparar los parámetros del path
|
184
|
+
path_params = request["path_params"] || {}
|
185
|
+
path_params.map { |k, v| "#{k}: #{v.inspect}" }.join(", ")
|
186
|
+
|
187
|
+
# Preparar los parámetros de la consulta y el cuerpo
|
188
|
+
query_params = request["params"] || {}
|
189
|
+
body = request["body"] || {}
|
190
|
+
|
191
|
+
# Construir la URL con los parámetros del path reemplazados
|
192
|
+
test_url = path.dup
|
193
|
+
path_params.each do |key, value|
|
194
|
+
test_url.gsub!(/\{#{key}\}/, value.to_s)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Si la URL comienza con http:// o https://, extraer solo el path
|
198
|
+
if test_url.start_with?("http://", "https://")
|
199
|
+
# Eliminar el protocolo y el dominio para quedarnos solo con el path
|
200
|
+
test_url = test_url.sub(%r{^https?://[^/]+}, "")
|
201
|
+
test_url = test_url[1..] if test_url.start_with?("/") # Quitar el slash inicial
|
202
|
+
end
|
203
|
+
|
204
|
+
# Construir los argumentos de la llamada
|
205
|
+
call_args = []
|
206
|
+
call_args.concat(path_params.values.map(&:inspect))
|
207
|
+
call_args << query_params.inspect if query_params.any?
|
208
|
+
call_args << body.inspect if body.any?
|
209
|
+
|
210
|
+
# Generar el código para verificar la respuesta
|
211
|
+
response_format = resource_config["response_format"] || global_config["response_format"] || {}
|
212
|
+
response_assertions = generate_response_assertions(module_name, endpoint_name, response, response_format)
|
213
|
+
|
214
|
+
<<~RUBY
|
215
|
+
def test_#{resource_name}_#{endpoint_name}_#{method_name_desc}
|
216
|
+
# Stub the HTTP request
|
217
|
+
status = #{response["status"] || 200}
|
218
|
+
response_body = #{response["body"].inspect}
|
219
|
+
|
220
|
+
@stubs.#{method}("#{test_url}") do |env|
|
221
|
+
# Verificar que los parámetros de consulta coincidan
|
222
|
+
if env.body.is_a?(String) && !env.body.empty?
|
223
|
+
request_body = JSON.parse(env.body)
|
224
|
+
# Aquí podrías agregar verificaciones de body si es necesario
|
225
|
+
end
|
226
|
+
|
227
|
+
[status, {'Content-Type' => 'application/json'}, response_body.is_a?(String) ? response_body : response_body.to_json]
|
228
|
+
end
|
229
|
+
|
230
|
+
client = #{module_name}::Client.new
|
231
|
+
|
232
|
+
#{handle_error_case(response)}
|
233
|
+
result = client.#{resource_name}.#{endpoint_name}(#{call_args.join(", ")})
|
234
|
+
|
235
|
+
#{response_assertions}
|
236
|
+
end
|
237
|
+
RUBY
|
238
|
+
end
|
239
|
+
|
240
|
+
def self.verify_request_env(query_params, body, method)
|
241
|
+
checks = []
|
242
|
+
|
243
|
+
if query_params.any?
|
244
|
+
params_checks = query_params.map do |key, value|
|
245
|
+
"assert_equal #{value.inspect}, Rack::Utils.parse_nested_query(env.url.query)[#{key.to_s.inspect}]"
|
246
|
+
end
|
247
|
+
checks.concat(params_checks)
|
248
|
+
end
|
249
|
+
|
250
|
+
if %w[post put patch].include?(method.to_s) && body.any?
|
251
|
+
checks << "request_body = JSON.parse(env.body)"
|
252
|
+
|
253
|
+
body_checks = body.map do |key, value|
|
254
|
+
"assert_equal #{value.inspect}, request_body[#{key.to_s.inspect}]"
|
255
|
+
end
|
256
|
+
checks.concat(body_checks)
|
257
|
+
end
|
258
|
+
|
259
|
+
checks.join("\n ")
|
260
|
+
end
|
261
|
+
|
262
|
+
def self.handle_error_case(response)
|
263
|
+
status = response["status"] || 200
|
264
|
+
|
265
|
+
if status >= 400
|
266
|
+
<<~RUBY
|
267
|
+
assert_raises(#{module_name}::Error) do
|
268
|
+
RUBY
|
269
|
+
else
|
270
|
+
""
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def self.generate_response_assertions(module_name, endpoint_name, response, response_format)
|
275
|
+
status = response["status"] || 200
|
276
|
+
|
277
|
+
if status >= 400
|
278
|
+
" end # assert_raises"
|
279
|
+
else
|
280
|
+
body = response["body"] || {}
|
281
|
+
|
282
|
+
# Verificar si el cuerpo es un hash antes de intentar usar key?
|
283
|
+
if body.is_a?(String)
|
284
|
+
# Si el cuerpo es una cadena (como en el caso de las imágenes binarias)
|
285
|
+
<<~RUBY
|
286
|
+
assert_instance_of #{module_name}::Object, result
|
287
|
+
# El resultado es probablemente una URL o datos binarios
|
288
|
+
RUBY
|
289
|
+
else
|
290
|
+
is_collection = %w[all list index search query].include?(endpoint_name) ||
|
291
|
+
(body.is_a?(Hash) && (body.key?("data") || body.key?(:data) ||
|
292
|
+
(response_format["collection_root"] &&
|
293
|
+
(body.key?(response_format["collection_root"]) ||
|
294
|
+
body.key?(response_format["collection_root"].to_sym)))))
|
295
|
+
|
296
|
+
if is_collection
|
297
|
+
collection_root = response_format["collection_root"] || "data"
|
298
|
+
items = body[collection_root] || body[collection_root.to_sym] || []
|
299
|
+
|
300
|
+
if items.empty?
|
301
|
+
<<~RUBY
|
302
|
+
assert_instance_of #{module_name}::Collection, result
|
303
|
+
assert_empty result.data
|
304
|
+
RUBY
|
305
|
+
else
|
306
|
+
<<~RUBY
|
307
|
+
assert_instance_of #{module_name}::Collection, result
|
308
|
+
assert_equal #{items.size}, result.data.size
|
309
|
+
|
310
|
+
# Verify first item properties
|
311
|
+
if result.data.any?
|
312
|
+
first_item = result.data.first
|
313
|
+
#{generate_item_assertions(items.first)}
|
314
|
+
end
|
315
|
+
RUBY
|
316
|
+
end
|
317
|
+
else
|
318
|
+
item_root = response_format["item_root"]
|
319
|
+
item = item_root ? (body[item_root] || body[item_root.to_sym] || {}) : body
|
320
|
+
|
321
|
+
<<~RUBY
|
322
|
+
assert_instance_of #{module_name}::Object, result
|
323
|
+
#{generate_item_assertions(item)}
|
324
|
+
RUBY
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def self.generate_item_assertions(item)
|
331
|
+
return "# No item data to assert" if !item || !item.is_a?(Hash) || item.empty?
|
332
|
+
|
333
|
+
item.map do |key, value|
|
334
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
335
|
+
"assert_not_nil result.#{key}"
|
336
|
+
else
|
337
|
+
"assert_equal #{value.inspect}, result.#{key}"
|
338
|
+
end
|
339
|
+
end.join("\n ")
|
340
|
+
end
|
341
|
+
|
342
|
+
def self.error_tests(module_name)
|
343
|
+
<<~RUBY
|
344
|
+
def test_error_handling
|
345
|
+
error = #{module_name}::Error.new("Test error", {error: "details"}, 400)
|
346
|
+
|
347
|
+
assert_equal "Test error", error.message
|
348
|
+
assert_equal({error: "details"}, error.body)
|
349
|
+
assert_equal 400, error.status
|
350
|
+
end
|
351
|
+
|
352
|
+
def test_http_error_response
|
353
|
+
@stubs.get("error_test") do
|
354
|
+
[404, {'Content-Type' => 'application/json'}, {error: "Resource not found"}.to_json]
|
355
|
+
end
|
356
|
+
|
357
|
+
error = assert_raises(#{module_name}::Error) do
|
358
|
+
#{module_name}::Request.new("error_test").get
|
359
|
+
end
|
360
|
+
|
361
|
+
assert_equal 404, error.status
|
362
|
+
assert_includes error.message, "Resource not found"
|
363
|
+
end
|
364
|
+
RUBY
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
data/lib/wrappix.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "wrappix/version"
|
4
|
+
require_relative "wrappix/builder"
|
5
|
+
require_relative "wrappix/configuration"
|
6
|
+
|
7
|
+
module Wrappix
|
8
|
+
class Error < StandardError; end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_accessor :configuration
|
12
|
+
|
13
|
+
def configure
|
14
|
+
self.configuration ||= Configuration.new
|
15
|
+
yield(configuration) if block_given?
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def build(config_file)
|
20
|
+
builder = Builder.new(config_file)
|
21
|
+
builder.build
|
22
|
+
rescue Errno::ENOENT => e
|
23
|
+
puts "Error: #{e.message}"
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
self.configuration = Configuration.new
|
29
|
+
end
|
data/sig/wrappix.rbs
ADDED
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wrappix
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bruno Costanzo
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-03-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '3.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: faraday_middleware
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: thor
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: vcr
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '6.1'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '6.1'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: webmock
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '3.18'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '3.18'
|
89
|
+
description: A wrapper builder for any API
|
90
|
+
email:
|
91
|
+
- dev.bcostanzo@gmail.com
|
92
|
+
executables:
|
93
|
+
- wrappix
|
94
|
+
extensions: []
|
95
|
+
extra_rdoc_files: []
|
96
|
+
files:
|
97
|
+
- ".rubocop.yml"
|
98
|
+
- CHANGELOG.md
|
99
|
+
- CODE_OF_CONDUCT.md
|
100
|
+
- LICENSE.txt
|
101
|
+
- README.md
|
102
|
+
- Rakefile
|
103
|
+
- bin/wrappix
|
104
|
+
- lib/wrappix.rb
|
105
|
+
- lib/wrappix/builder.rb
|
106
|
+
- lib/wrappix/cli.rb
|
107
|
+
- lib/wrappix/client.rb
|
108
|
+
- lib/wrappix/configuration.rb
|
109
|
+
- lib/wrappix/request.rb
|
110
|
+
- lib/wrappix/templates/cache.rb
|
111
|
+
- lib/wrappix/templates/client.rb
|
112
|
+
- lib/wrappix/templates/collection.rb
|
113
|
+
- lib/wrappix/templates/configuration.rb
|
114
|
+
- lib/wrappix/templates/documentation.rb
|
115
|
+
- lib/wrappix/templates/error.rb
|
116
|
+
- lib/wrappix/templates/main.rb
|
117
|
+
- lib/wrappix/templates/object.rb
|
118
|
+
- lib/wrappix/templates/readme.rb
|
119
|
+
- lib/wrappix/templates/request.rb
|
120
|
+
- lib/wrappix/templates/resource.rb
|
121
|
+
- lib/wrappix/templates/tests.rb
|
122
|
+
- lib/wrappix/version.rb
|
123
|
+
- sig/wrappix.rbs
|
124
|
+
homepage: https://github.com/bruno-costanzo/wrappix
|
125
|
+
licenses:
|
126
|
+
- MIT
|
127
|
+
metadata:
|
128
|
+
homepage_uri: https://github.com/bruno-costanzo/wrappix
|
129
|
+
source_code_uri: https://github.com/bruno-costanzo/wrappix
|
130
|
+
changelog_uri: https://github.com/bruno-costanzo/wrappix/blob/main/CHANGELOG.md
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 3.1.0
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
requirements: []
|
146
|
+
rubygems_version: 3.5.16
|
147
|
+
signing_key:
|
148
|
+
specification_version: 4
|
149
|
+
summary: A wrapper builder for any API
|
150
|
+
test_files: []
|