aitch 1.0.1 → 1.2.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 +5 -5
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/tests.yml +50 -0
- data/.rubocop.yml +26 -0
- data/Gemfile +2 -2
- data/README.md +54 -14
- data/Rakefile +5 -1
- data/aitch.gemspec +12 -7
- data/lib/aitch/configuration.rb +5 -0
- data/lib/aitch/dsl.rb +4 -3
- data/lib/aitch/engines/json.rb +15 -0
- data/lib/aitch/errors.rb +1 -0
- data/lib/aitch/ext/to_query.rb +6 -10
- data/lib/aitch/location.rb +4 -3
- data/lib/aitch/namespace.rb +38 -14
- data/lib/aitch/redirect.rb +1 -0
- data/lib/aitch/request.rb +40 -28
- data/lib/aitch/response/body.rb +1 -0
- data/lib/aitch/response/description.rb +3 -2
- data/lib/aitch/response/errors.rb +2 -1
- data/lib/aitch/response.rb +9 -5
- data/lib/aitch/response_parser/default_parser.rb +2 -1
- data/lib/aitch/response_parser/html_parser.rb +1 -0
- data/lib/aitch/response_parser/json_parser.rb +2 -1
- data/lib/aitch/response_parser/xml_parser.rb +1 -0
- data/lib/aitch/response_parser.rb +8 -5
- data/lib/aitch/uri.rb +5 -2
- data/lib/aitch/utils.rb +3 -1
- data/lib/aitch/version.rb +2 -1
- data/lib/aitch.rb +13 -13
- data/test/aitch/aitch_test.rb +1 -0
- data/test/aitch/configuration_test.rb +2 -1
- data/test/aitch/dsl_test.rb +1 -0
- data/test/aitch/execute_test.rb +1 -0
- data/test/aitch/namespace_test.rb +2 -1
- data/test/aitch/request/client_https_test.rb +1 -0
- data/test/aitch/request/follow_redirect_test.rb +4 -3
- data/test/aitch/request/json_request_test.rb +1 -0
- data/test/aitch/request/request_class_test.rb +3 -2
- data/test/aitch/request/status_code_validation_test.rb +3 -2
- data/test/aitch/request_test.rb +45 -8
- data/test/aitch/response/custom_response_parser_test.rb +1 -4
- data/test/aitch/response/default_response_parser_test.rb +14 -0
- data/test/aitch/response/errors_test.rb +1 -0
- data/test/aitch/response/html_response_test.rb +1 -0
- data/test/aitch/response/json_response_test.rb +2 -1
- data/test/aitch/response/raw_response_test.rb +1 -0
- data/test/aitch/response/status_3xx_test.rb +1 -0
- data/test/aitch/response/status_4xx_test.rb +1 -0
- data/test/aitch/response/status_5xx_test.rb +1 -0
- data/test/aitch/response/xml_response_test.rb +1 -0
- data/test/aitch/response_parser/html_parser_test.rb +1 -0
- data/test/aitch/response_parser/json_parser_test.rb +2 -1
- data/test/aitch/response_parser/xml_parser_test.rb +1 -1
- data/test/aitch/response_test.rb +1 -1
- data/test/aitch/to_query_test.rb +28 -0
- data/test/aitch/uri_test.rb +2 -1
- data/test/aitch/utils/symbolize_keys_test.rb +1 -0
- data/test/aitch/utils/underscore_test.rb +1 -0
- data/test/support/helpers.rb +5 -4
- data/test/test_helper.rb +3 -2
- metadata +77 -15
- data/.travis.yml +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a3f4cd3269e5b709f85e34148b2ed6aad4a9080f9903dc625d4840d8ffc2293a
|
4
|
+
data.tar.gz: d97a344ec31e5f6ba528f1d359b96aa2860ab51e1cdde507d5cbc0557e9a75a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a11acc6e165677b372cd4c9a07b9fd33640611a056fb1c437917ffa1d89ab0520bcaf9943cd5e8f72a3f088942a8f7b9d968a59ec7207dc6a061f54364216aba
|
7
|
+
data.tar.gz: a0228f9d4719ee0fddd2932fece69c454062d40f4526612b41044168198f7ec91478267163e343a995ceb5f8bbcdc1d4d228d8edb73a9845b5aa0d08145581c9
|
data/.github/FUNDING.yml
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
---
|
2
|
+
name: Tests
|
3
|
+
|
4
|
+
on:
|
5
|
+
pull_request:
|
6
|
+
branches:
|
7
|
+
- main
|
8
|
+
push:
|
9
|
+
branches:
|
10
|
+
- main
|
11
|
+
jobs:
|
12
|
+
build:
|
13
|
+
name: Tests with Ruby ${{ matrix.ruby }}
|
14
|
+
runs-on: "ubuntu-latest"
|
15
|
+
strategy:
|
16
|
+
fail-fast: false
|
17
|
+
matrix:
|
18
|
+
ruby: ["2.7.x", "2.6.x", "2.5.x", "3.0.x", "3.1.x"]
|
19
|
+
|
20
|
+
steps:
|
21
|
+
- uses: actions/checkout@v1
|
22
|
+
|
23
|
+
- uses: actions/cache@v2
|
24
|
+
with:
|
25
|
+
path: vendor/bundle
|
26
|
+
key: >
|
27
|
+
${{ runner.os }}-${{ matrix.ruby }}-gems-${{
|
28
|
+
hashFiles('aitch.gemspec') }}
|
29
|
+
restore-keys: >
|
30
|
+
${{ runner.os }}-${{ matrix.ruby }}-gems-${{
|
31
|
+
hashFiles('aitch.gemspec') }}
|
32
|
+
|
33
|
+
- name: Set up Ruby
|
34
|
+
uses: actions/setup-ruby@v1
|
35
|
+
with:
|
36
|
+
ruby-version: ${{ matrix.ruby }}
|
37
|
+
|
38
|
+
- name: Install gem dependencies
|
39
|
+
env:
|
40
|
+
RAILS_ENV: test
|
41
|
+
run: |
|
42
|
+
gem install bundler
|
43
|
+
bundle config path vendor/bundle
|
44
|
+
bundle update --jobs 4 --retry 3
|
45
|
+
|
46
|
+
- name: Run Tests
|
47
|
+
env:
|
48
|
+
RAILS_ENV: test
|
49
|
+
run: |
|
50
|
+
bundle exec rake
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
---
|
2
|
+
inherit_gem:
|
3
|
+
rubocop-fnando: .rubocop.yml
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
TargetRubyVersion: 2.5
|
7
|
+
|
8
|
+
Layout/LineLength:
|
9
|
+
Exclude:
|
10
|
+
- test/**/*.rb
|
11
|
+
|
12
|
+
Naming/AccessorMethodName:
|
13
|
+
Exclude:
|
14
|
+
- lib/aitch/request.rb
|
15
|
+
|
16
|
+
Metrics/ClassLength:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
Metrics/AbcSize:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Metrics/MethodLength:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Metrics/ParameterLists:
|
26
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
# Aitch
|
2
2
|
|
3
|
-
[](https://github.com/fnando/aitch)
|
4
4
|
[](https://codeclimate.com/github/fnando/aitch)
|
5
|
-
[](https://rubygems.org/gems/aitch)
|
6
|
+
[](https://rubygems.org/gems/aitch)
|
7
7
|
|
8
8
|
A simple HTTP client.
|
9
9
|
|
10
10
|
Features:
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
- Supports Gzip|Deflate response
|
13
|
+
- Automatically parses JSON, HTML and XML responses
|
14
|
+
- Automatically follows redirect
|
15
15
|
|
16
16
|
## Installation
|
17
17
|
|
18
18
|
Add this line to your application's Gemfile:
|
19
19
|
|
20
20
|
```ruby
|
21
|
-
gem
|
21
|
+
gem "aitch"
|
22
22
|
```
|
23
23
|
|
24
24
|
And then execute:
|
@@ -54,6 +54,9 @@ Aitch.configure do |config|
|
|
54
54
|
|
55
55
|
# Set the logger.
|
56
56
|
config.logger = nil
|
57
|
+
|
58
|
+
# Set the base url.
|
59
|
+
config.base_url = nil
|
57
60
|
end
|
58
61
|
```
|
59
62
|
|
@@ -83,6 +86,17 @@ response = Aitch.get do
|
|
83
86
|
end
|
84
87
|
```
|
85
88
|
|
89
|
+
Finally, you can use keyword arguments:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
Aitch.get(
|
93
|
+
url: "http://example.org",
|
94
|
+
params: {a: 1, b: 2},
|
95
|
+
headers: {Authorization: "Token token=abc"},
|
96
|
+
options: {follow_redirect: false}
|
97
|
+
)
|
98
|
+
```
|
99
|
+
|
86
100
|
### Response
|
87
101
|
|
88
102
|
The response object:
|
@@ -104,7 +118,8 @@ response.data # Parsed response body
|
|
104
118
|
|
105
119
|
#### Parsing JSON, XML and HTML with Nokogiri
|
106
120
|
|
107
|
-
If your response is a JSON, XML or a HTML content type, we'll automatically
|
121
|
+
If your response is a JSON, XML or a HTML content type, we'll automatically
|
122
|
+
convert the response into the appropriate object.
|
108
123
|
|
109
124
|
```ruby
|
110
125
|
response = Aitch.get("http://simplesideias.com.br")
|
@@ -148,7 +163,8 @@ The request:
|
|
148
163
|
Aitch.get("http://example.org")
|
149
164
|
```
|
150
165
|
|
151
|
-
If the redirect limit is exceeded, then the `Aitch::TooManyRedirectsError`
|
166
|
+
If the redirect limit is exceeded, then the `Aitch::TooManyRedirectsError`
|
167
|
+
exception is raised.
|
152
168
|
|
153
169
|
### Basic auth
|
154
170
|
|
@@ -196,7 +212,8 @@ Request.get("http://example.org")
|
|
196
212
|
|
197
213
|
### Validating responses
|
198
214
|
|
199
|
-
When you know the kind of response you're expecting, you can validate it by
|
215
|
+
When you know the kind of response you're expecting, you can validate it by
|
216
|
+
specifying the `expect` option.
|
200
217
|
|
201
218
|
```ruby
|
202
219
|
Aitch.get do
|
@@ -205,7 +222,8 @@ Aitch.get do
|
|
205
222
|
end
|
206
223
|
```
|
207
224
|
|
208
|
-
If this request receives anything other than `200`, it will raise a
|
225
|
+
If this request receives anything other than `200`, it will raise a
|
226
|
+
`Aitch::StatusCodeError` exception.
|
209
227
|
|
210
228
|
```
|
211
229
|
Expect(200 OK) <=> Actual(404 Not Found)
|
@@ -215,7 +233,10 @@ You can also provide a list of accepted statuses, like `expect: [200, 201]`.
|
|
215
233
|
|
216
234
|
### Response Parsers
|
217
235
|
|
218
|
-
You can register new response parsers by using
|
236
|
+
You can register new response parsers by using
|
237
|
+
`Aitch::ResponseParser.register(name, parser)`, where parser must implement the
|
238
|
+
methods `match?(content_type)` and `load(response_body)`. This is how you could
|
239
|
+
load CSV values.
|
219
240
|
|
220
241
|
```ruby
|
221
242
|
require "csv"
|
@@ -237,7 +258,8 @@ end
|
|
237
258
|
Aitch::ResponseParser.prepend(:csv, CSVParser)
|
238
259
|
```
|
239
260
|
|
240
|
-
The default behavior is returning the response body. You can replace it as the
|
261
|
+
The default behavior is returning the response body. You can replace it as the
|
262
|
+
following:
|
241
263
|
|
242
264
|
```ruby
|
243
265
|
module DefaultParser
|
@@ -261,13 +283,31 @@ Aitch::ResponseParser.append(:default, DefaultParser)
|
|
261
283
|
|
262
284
|
Aitch comes with response parsers for HTML, XML and JSON.
|
263
285
|
|
264
|
-
By default, the JSON parser will be `JSON`. To set it to something else, use
|
286
|
+
By default, the JSON parser will be `JSON`. To set it to something else, use
|
287
|
+
`Aitch::ResponseParser::JSONParser.engine`.
|
265
288
|
|
266
289
|
```ruby
|
267
290
|
require "oj"
|
268
291
|
Aitch::ResponseParser::JSONParser.engine = Oj
|
269
292
|
```
|
270
293
|
|
294
|
+
### Setting the base url
|
295
|
+
|
296
|
+
When you're creating a wrapper for an API, usually the hostname is the same for
|
297
|
+
the whole API. In this case, you can avoid having to pass it around all the time
|
298
|
+
by setting `Aitch::Configuration#base_url`. This option is meant to be used when
|
299
|
+
you instantiate a new namespace.
|
300
|
+
|
301
|
+
```ruby
|
302
|
+
Client = Aitch::Namespace.new
|
303
|
+
|
304
|
+
Client.configure do |config|
|
305
|
+
config.base_url = "https://api.example.com"
|
306
|
+
end
|
307
|
+
|
308
|
+
Client.get("/users")
|
309
|
+
```
|
310
|
+
|
271
311
|
## Contributing
|
272
312
|
|
273
313
|
1. Fork it
|
data/Rakefile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "bundler/gem_tasks"
|
3
4
|
require "rake/testtask"
|
5
|
+
require "rubocop/rake_task"
|
4
6
|
|
5
7
|
Rake::TestTask.new(:test) do |t|
|
6
8
|
t.libs << "test"
|
@@ -8,4 +10,6 @@ Rake::TestTask.new(:test) do |t|
|
|
8
10
|
t.warning = false
|
9
11
|
end
|
10
12
|
|
11
|
-
|
13
|
+
RuboCop::RakeTask.new
|
14
|
+
|
15
|
+
task default: %i[test rubocop]
|
data/aitch.gemspec
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "./lib/aitch/version"
|
2
4
|
|
3
5
|
Gem::Specification.new do |spec|
|
@@ -9,20 +11,23 @@ Gem::Specification.new do |spec|
|
|
9
11
|
spec.summary = spec.description
|
10
12
|
spec.homepage = "http://rubygems.org/gems/aitch"
|
11
13
|
spec.license = "MIT"
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
|
12
15
|
|
13
|
-
spec.files = `git ls-files`.split(
|
14
|
-
spec.executables = spec.files.grep(%r{^bin/}) {
|
16
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f) }
|
15
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
16
19
|
spec.require_paths = ["lib"]
|
17
20
|
|
18
|
-
spec.
|
19
|
-
|
20
|
-
spec.add_dependency "nokogiri", ">= 1.6.0"
|
21
|
+
spec.add_dependency "nokogiri"
|
21
22
|
|
22
|
-
spec.add_development_dependency "codeclimate-test-reporter"
|
23
23
|
spec.add_development_dependency "bundler"
|
24
|
-
spec.add_development_dependency "
|
24
|
+
spec.add_development_dependency "minitest"
|
25
25
|
spec.add_development_dependency "minitest-utils"
|
26
26
|
spec.add_development_dependency "mocha"
|
27
|
+
spec.add_development_dependency "pry-meta"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
spec.add_development_dependency "rubocop"
|
30
|
+
spec.add_development_dependency "rubocop-fnando"
|
31
|
+
spec.add_development_dependency "simplecov"
|
27
32
|
spec.add_development_dependency "webmock"
|
28
33
|
end
|
data/lib/aitch/configuration.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Aitch
|
3
4
|
class Configuration
|
4
5
|
# Set proxy.
|
@@ -22,12 +23,16 @@ module Aitch
|
|
22
23
|
# Set the logger.
|
23
24
|
attr_accessor :logger
|
24
25
|
|
26
|
+
# Set the base url.
|
27
|
+
attr_accessor :base_url
|
28
|
+
|
25
29
|
def initialize
|
26
30
|
@timeout = 10
|
27
31
|
@redirect_limit = 5
|
28
32
|
@follow_redirect = true
|
29
33
|
@user_agent = "Aitch/#{Aitch::VERSION} (http://rubygems.org/gems/aitch)"
|
30
34
|
@default_headers = {}
|
35
|
+
@base_url = nil
|
31
36
|
end
|
32
37
|
|
33
38
|
def to_h
|
data/lib/aitch/dsl.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Aitch
|
3
4
|
class DSL
|
4
5
|
%w[url options headers data].each do |name|
|
5
|
-
class_eval
|
6
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
6
7
|
attr_writer :#{name}
|
7
8
|
|
8
9
|
def #{name}(*args)
|
@@ -12,8 +13,8 @@ module Aitch
|
|
12
13
|
RUBY
|
13
14
|
end
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
alias params data
|
17
|
+
alias body data
|
17
18
|
|
18
19
|
def to_h
|
19
20
|
{
|
data/lib/aitch/errors.rb
CHANGED
data/lib/aitch/ext/to_query.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "cgi"
|
3
4
|
|
4
5
|
class Object
|
@@ -36,23 +37,18 @@ class FalseClass
|
|
36
37
|
end
|
37
38
|
|
38
39
|
class Array
|
39
|
-
# Calls <tt>to_param</tt> on all its elements and joins the result with
|
40
|
-
# slashes. This is used by <tt>url_for</tt> in Action Pack.
|
41
|
-
def to_param
|
42
|
-
collect { |e| e.to_param }.join '/'
|
43
|
-
end
|
44
|
-
|
45
40
|
# Converts an array into a string suitable for use as a URL query string,
|
46
41
|
# using the given +key+ as the param name.
|
47
42
|
#
|
48
|
-
# [
|
43
|
+
# ["Rails", "coding"].to_query("hobbies")
|
44
|
+
# # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
|
49
45
|
def to_query(key)
|
50
46
|
prefix = "#{key}[]"
|
51
47
|
|
52
48
|
if empty?
|
53
49
|
nil.to_query(prefix)
|
54
50
|
else
|
55
|
-
collect {
|
51
|
+
collect {|value| value.to_query(prefix) }.join "&"
|
56
52
|
end
|
57
53
|
end
|
58
54
|
end
|
@@ -78,8 +74,8 @@ class Hash
|
|
78
74
|
unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
|
79
75
|
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
80
76
|
end
|
81
|
-
end.compact.sort! *
|
77
|
+
end.compact.sort! * "&"
|
82
78
|
end
|
83
79
|
|
84
|
-
|
80
|
+
alias to_param to_query
|
85
81
|
end
|
data/lib/aitch/location.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Aitch
|
3
4
|
class Location
|
4
5
|
attr_reader :redirect_stack, :current_url
|
@@ -9,7 +10,7 @@ module Aitch
|
|
9
10
|
end
|
10
11
|
|
11
12
|
def location
|
12
|
-
return current_url unless current_url.match(%r
|
13
|
+
return current_url unless current_url.match?(%r{\A/}) # rubocop:disable Performance/StartWith
|
13
14
|
|
14
15
|
uri = find_uri_with_host
|
15
16
|
url = ["#{uri.scheme}://#{uri.hostname}"]
|
@@ -20,8 +21,8 @@ module Aitch
|
|
20
21
|
|
21
22
|
def find_uri_with_host
|
22
23
|
redirect_stack.reverse
|
23
|
-
|
24
|
-
|
24
|
+
.map {|url| ::URI.parse(url) }
|
25
|
+
.find(&:scheme)
|
25
26
|
end
|
26
27
|
end
|
27
28
|
end
|
data/lib/aitch/namespace.rb
CHANGED
@@ -1,17 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Aitch
|
3
4
|
class Namespace
|
4
|
-
def configure
|
5
|
+
def configure
|
5
6
|
yield config
|
6
7
|
end
|
7
8
|
|
8
9
|
def config
|
9
10
|
@config ||= Configuration.new
|
10
11
|
end
|
11
|
-
|
12
|
+
alias configuration config
|
13
|
+
|
14
|
+
def execute(
|
15
|
+
request_method: nil,
|
16
|
+
url: nil,
|
17
|
+
params: nil,
|
18
|
+
data: nil,
|
19
|
+
body: nil,
|
20
|
+
headers: nil,
|
21
|
+
options: nil,
|
22
|
+
&block
|
23
|
+
)
|
24
|
+
data = data || params || body || {}
|
25
|
+
headers ||= {}
|
26
|
+
options ||= {}
|
12
27
|
|
13
|
-
|
14
|
-
if block_given?
|
28
|
+
if block
|
15
29
|
dsl = DSL.new
|
16
30
|
dsl.instance_eval(&block)
|
17
31
|
args = dsl.to_h
|
@@ -24,17 +38,18 @@ module Aitch
|
|
24
38
|
}
|
25
39
|
end
|
26
40
|
|
27
|
-
args
|
28
|
-
|
29
|
-
options: config.to_h.merge(Utils.symbolize_keys(args[:options]))
|
30
|
-
)
|
41
|
+
args[:request_method] = request_method
|
42
|
+
args[:options] = config.to_h.merge(Utils.symbolize_keys(args[:options]))
|
31
43
|
|
32
44
|
Request.new(args).perform
|
33
45
|
end
|
34
46
|
|
35
47
|
def execute!(*args, &block)
|
36
|
-
|
48
|
+
options = extract_args!(args)
|
49
|
+
response = execute(**options, &block)
|
50
|
+
|
37
51
|
raise response.error if response.error?
|
52
|
+
|
38
53
|
response
|
39
54
|
end
|
40
55
|
|
@@ -47,14 +62,23 @@ module Aitch
|
|
47
62
|
options
|
48
63
|
trace
|
49
64
|
head
|
50
|
-
].each do |
|
51
|
-
define_method(
|
52
|
-
|
65
|
+
].each do |request_method|
|
66
|
+
define_method(request_method) do |*args, &block|
|
67
|
+
options = extract_args!(args)
|
68
|
+
execute(**options.merge(request_method: request_method), &block)
|
53
69
|
end
|
54
70
|
|
55
|
-
define_method("#{
|
56
|
-
|
71
|
+
define_method("#{request_method}!") do |*args, &block|
|
72
|
+
options = extract_args!(args)
|
73
|
+
|
74
|
+
execute!(**options.merge(request_method: request_method), &block)
|
57
75
|
end
|
58
76
|
end
|
77
|
+
|
78
|
+
private def extract_args!(args)
|
79
|
+
return args.first if args.size == 1 && args.first.is_a?(Hash)
|
80
|
+
|
81
|
+
%i[url data headers options].zip(args).to_h
|
82
|
+
end
|
59
83
|
end
|
60
84
|
end
|