evil-client 0.3.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +0 -11
- data/.gitignore +1 -0
- data/.rspec +0 -1
- data/.rubocop.yml +22 -19
- data/.travis.yml +1 -0
- data/CHANGELOG.md +251 -6
- data/LICENSE.txt +3 -1
- data/README.md +47 -81
- data/docs/helpers/body.md +93 -0
- data/docs/helpers/connection.md +19 -0
- data/docs/helpers/headers.md +72 -0
- data/docs/helpers/http_method.md +39 -0
- data/docs/helpers/let.md +14 -0
- data/docs/helpers/logger.md +24 -0
- data/docs/helpers/middleware.md +56 -0
- data/docs/helpers/operation.md +103 -0
- data/docs/helpers/option.md +50 -0
- data/docs/helpers/path.md +37 -0
- data/docs/helpers/query.md +59 -0
- data/docs/helpers/response.md +40 -0
- data/docs/helpers/scope.md +121 -0
- data/docs/helpers/security.md +102 -0
- data/docs/helpers/validate.md +68 -0
- data/docs/index.md +70 -78
- data/docs/license.md +5 -1
- data/docs/rspec.md +96 -0
- data/evil-client.gemspec +10 -8
- data/lib/evil/client.rb +126 -72
- data/lib/evil/client/builder.rb +47 -0
- data/lib/evil/client/builder/operation.rb +40 -0
- data/lib/evil/client/builder/scope.rb +31 -0
- data/lib/evil/client/chaining.rb +17 -0
- data/lib/evil/client/connection.rb +60 -20
- data/lib/evil/client/container.rb +66 -0
- data/lib/evil/client/container/operation.rb +23 -0
- data/lib/evil/client/container/scope.rb +28 -0
- data/lib/evil/client/exceptions/definition_error.rb +15 -0
- data/lib/evil/client/exceptions/name_error.rb +32 -0
- data/lib/evil/client/exceptions/response_error.rb +42 -0
- data/lib/evil/client/exceptions/type_error.rb +29 -0
- data/lib/evil/client/exceptions/validation_error.rb +27 -0
- data/lib/evil/client/formatter.rb +49 -0
- data/lib/evil/client/formatter/form.rb +45 -0
- data/lib/evil/client/formatter/multipart.rb +33 -0
- data/lib/evil/client/formatter/part.rb +66 -0
- data/lib/evil/client/formatter/text.rb +21 -0
- data/lib/evil/client/resolver.rb +84 -0
- data/lib/evil/client/resolver/body.rb +22 -0
- data/lib/evil/client/resolver/format.rb +30 -0
- data/lib/evil/client/resolver/headers.rb +46 -0
- data/lib/evil/client/resolver/http_method.rb +34 -0
- data/lib/evil/client/resolver/middleware.rb +36 -0
- data/lib/evil/client/resolver/query.rb +39 -0
- data/lib/evil/client/resolver/request.rb +96 -0
- data/lib/evil/client/resolver/response.rb +26 -0
- data/lib/evil/client/resolver/security.rb +113 -0
- data/lib/evil/client/resolver/uri.rb +35 -0
- data/lib/evil/client/rspec.rb +127 -0
- data/lib/evil/client/schema.rb +105 -0
- data/lib/evil/client/schema/operation.rb +177 -0
- data/lib/evil/client/schema/scope.rb +73 -0
- data/lib/evil/client/settings.rb +172 -0
- data/lib/evil/client/settings/validator.rb +64 -0
- data/mkdocs.yml +21 -15
- data/spec/features/custom_connection_spec.rb +17 -0
- data/spec/features/operation/middleware_spec.rb +50 -0
- data/spec/features/operation/options_spec.rb +71 -0
- data/spec/features/operation/request_spec.rb +94 -0
- data/spec/features/operation/response_spec.rb +48 -0
- data/spec/features/scope/options_spec.rb +52 -0
- data/spec/fixtures/locales/en.yml +16 -0
- data/spec/fixtures/test_client.rb +76 -0
- data/spec/spec_helper.rb +18 -6
- data/spec/support/fixtures_helper.rb +7 -0
- data/spec/unit/builder/operation_spec.rb +90 -0
- data/spec/unit/builder/scope_spec.rb +84 -0
- data/spec/unit/client_spec.rb +137 -0
- data/spec/unit/connection_spec.rb +78 -0
- data/spec/unit/container/operation_spec.rb +81 -0
- data/spec/unit/container/scope_spec.rb +61 -0
- data/spec/unit/container_spec.rb +107 -0
- data/spec/unit/exceptions/definition_error_spec.rb +15 -0
- data/spec/unit/exceptions/name_error_spec.rb +77 -0
- data/spec/unit/exceptions/response_error_spec.rb +22 -0
- data/spec/unit/exceptions/type_error_spec.rb +71 -0
- data/spec/unit/exceptions/validation_error_spec.rb +13 -0
- data/spec/unit/formatter/form_spec.rb +27 -0
- data/spec/unit/formatter/multipart_spec.rb +23 -0
- data/spec/unit/formatter/part_spec.rb +49 -0
- data/spec/unit/formatter/text_spec.rb +37 -0
- data/spec/unit/formatter_spec.rb +46 -0
- data/spec/unit/resolver/body_spec.rb +65 -0
- data/spec/unit/resolver/format_spec.rb +66 -0
- data/spec/unit/resolver/headers_spec.rb +93 -0
- data/spec/unit/resolver/http_method_spec.rb +67 -0
- data/spec/unit/resolver/middleware_spec.rb +83 -0
- data/spec/unit/resolver/query_spec.rb +85 -0
- data/spec/unit/resolver/request_spec.rb +121 -0
- data/spec/unit/resolver/response_spec.rb +64 -0
- data/spec/unit/resolver/security_spec.rb +156 -0
- data/spec/unit/resolver/uri_spec.rb +117 -0
- data/spec/unit/rspec_spec.rb +342 -0
- data/spec/unit/schema/operation_spec.rb +309 -0
- data/spec/unit/schema/scope_spec.rb +110 -0
- data/spec/unit/schema_spec.rb +157 -0
- data/spec/unit/settings/validator_spec.rb +128 -0
- data/spec/unit/settings_spec.rb +248 -0
- metadata +192 -135
- data/docs/base_url.md +0 -38
- data/docs/documentation.md +0 -9
- data/docs/headers.md +0 -59
- data/docs/http_method.md +0 -31
- data/docs/model.md +0 -173
- data/docs/operation.md +0 -0
- data/docs/overview.md +0 -0
- data/docs/path.md +0 -48
- data/docs/query.md +0 -99
- data/docs/responses.md +0 -66
- data/docs/security.md +0 -102
- data/docs/settings.md +0 -32
- data/lib/evil/client/connection/net_http.rb +0 -57
- data/lib/evil/client/dsl.rb +0 -127
- data/lib/evil/client/dsl/base.rb +0 -26
- data/lib/evil/client/dsl/files.rb +0 -37
- data/lib/evil/client/dsl/headers.rb +0 -16
- data/lib/evil/client/dsl/http_method.rb +0 -24
- data/lib/evil/client/dsl/operation.rb +0 -91
- data/lib/evil/client/dsl/operations.rb +0 -41
- data/lib/evil/client/dsl/path.rb +0 -25
- data/lib/evil/client/dsl/query.rb +0 -16
- data/lib/evil/client/dsl/response.rb +0 -61
- data/lib/evil/client/dsl/responses.rb +0 -29
- data/lib/evil/client/dsl/scope.rb +0 -27
- data/lib/evil/client/dsl/security.rb +0 -57
- data/lib/evil/client/dsl/verifier.rb +0 -35
- data/lib/evil/client/middleware.rb +0 -81
- data/lib/evil/client/middleware/base.rb +0 -11
- data/lib/evil/client/middleware/merge_security.rb +0 -20
- data/lib/evil/client/middleware/normalize_headers.rb +0 -17
- data/lib/evil/client/middleware/stringify_form.rb +0 -40
- data/lib/evil/client/middleware/stringify_json.rb +0 -19
- data/lib/evil/client/middleware/stringify_multipart.rb +0 -36
- data/lib/evil/client/middleware/stringify_multipart/part.rb +0 -36
- data/lib/evil/client/middleware/stringify_query.rb +0 -35
- data/lib/evil/client/operation.rb +0 -34
- data/lib/evil/client/operation/request.rb +0 -26
- data/lib/evil/client/operation/response.rb +0 -39
- data/lib/evil/client/operation/response_error.rb +0 -13
- data/lib/evil/client/operation/unexpected_response_error.rb +0 -19
- data/spec/features/instantiation_spec.rb +0 -68
- data/spec/features/middleware_spec.rb +0 -79
- data/spec/features/operation_with_documentation_spec.rb +0 -41
- data/spec/features/operation_with_files_spec.rb +0 -40
- data/spec/features/operation_with_form_body_spec.rb +0 -158
- data/spec/features/operation_with_headers_spec.rb +0 -99
- data/spec/features/operation_with_http_method_spec.rb +0 -45
- data/spec/features/operation_with_json_body_spec.rb +0 -156
- data/spec/features/operation_with_nested_responses_spec.rb +0 -95
- data/spec/features/operation_with_path_spec.rb +0 -47
- data/spec/features/operation_with_query_spec.rb +0 -84
- data/spec/features/operation_with_security_spec.rb +0 -228
- data/spec/features/scoping_spec.rb +0 -48
- data/spec/support/test_client.rb +0 -15
- data/spec/unit/evil/client/connection/net_http_spec.rb +0 -38
- data/spec/unit/evil/client/dsl/files_spec.rb +0 -37
- data/spec/unit/evil/client/dsl/operation_spec.rb +0 -374
- data/spec/unit/evil/client/dsl/operations_spec.rb +0 -29
- data/spec/unit/evil/client/dsl/scope_spec.rb +0 -32
- data/spec/unit/evil/client/dsl/security_spec.rb +0 -135
- data/spec/unit/evil/client/middleware/merge_security_spec.rb +0 -32
- data/spec/unit/evil/client/middleware/normalize_headers_spec.rb +0 -17
- data/spec/unit/evil/client/middleware/stringify_form_spec.rb +0 -63
- data/spec/unit/evil/client/middleware/stringify_json_spec.rb +0 -61
- data/spec/unit/evil/client/middleware/stringify_multipart/part_spec.rb +0 -59
- data/spec/unit/evil/client/middleware/stringify_multipart_spec.rb +0 -62
- data/spec/unit/evil/client/middleware/stringify_query_spec.rb +0 -40
- data/spec/unit/evil/client/middleware_spec.rb +0 -46
- data/spec/unit/evil/client/operation/request_spec.rb +0 -49
- data/spec/unit/evil/client/operation/response_spec.rb +0 -63
data/docs/responses.md
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
For every operation you have to describe all expected responses and how they should be processed.
|
2
|
-
|
3
|
-
Use the `response` method with anexpected http response status(es):
|
4
|
-
|
5
|
-
```ruby
|
6
|
-
operation :find_cat do
|
7
|
-
# ...
|
8
|
-
response 200, 201
|
9
|
-
end
|
10
|
-
```
|
11
|
-
|
12
|
-
This definition tells a client to accept responses with given statuses, and to return an instance of `Rack::Response`.
|
13
|
-
|
14
|
-
```ruby
|
15
|
-
client.operations[:find_cat].call
|
16
|
-
# => #<Rack::Response @code=200 ...>
|
17
|
-
```
|
18
|
-
|
19
|
-
## Data Coersion
|
20
|
-
|
21
|
-
Instead of returning a raw rack response, you can coerce it using a block. The block will take 3 options, namely the response, its body and headers:
|
22
|
-
|
23
|
-
```ruby
|
24
|
-
operation :find_cat do |settings| # remember that you have access to settings
|
25
|
-
# ...
|
26
|
-
response 200 do |response:, body:, headers:|
|
27
|
-
JSON.parse(body) if settings.format == "json"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# later at a runtime
|
32
|
-
client.operations[:find_cat].call
|
33
|
-
# => { name: "Bastet", age: 10 }
|
34
|
-
```
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
## Raising Exceptions
|
39
|
-
|
40
|
-
When processing responces with error statuses you may need to raise an exception instead of returning values. Do this using option `raise: true`
|
41
|
-
|
42
|
-
```ruby
|
43
|
-
operation :find_cat do
|
44
|
-
# ...
|
45
|
-
response 422, raise: true
|
46
|
-
end
|
47
|
-
```
|
48
|
-
|
49
|
-
This time the operation will raise a `Evil::Client::ResponseError` (inherited from the `RuntimeError`). The exception carries a rack response:
|
50
|
-
|
51
|
-
```ruby
|
52
|
-
begin
|
53
|
-
client.operations[:find_cat].call
|
54
|
-
rescue Evil::Client::ResponseError => error
|
55
|
-
error.response
|
56
|
-
# => #<Rack::Response @code=422 ...>
|
57
|
-
end
|
58
|
-
```
|
59
|
-
|
60
|
-
Like before, you can add a block to handle the response. In this case an exception will carry a result of the block.
|
61
|
-
|
62
|
-
## Unexpected Responses
|
63
|
-
|
64
|
-
In case the server responded with undefined status, the operation raises `Evil::Client::UnexpectedResponseError` (inherited from the `RuntimeError`) that carries a rack response just like the `Evil::Client::ResponseError` before.
|
65
|
-
|
66
|
-
Notice that you can declare default responses using anonymous `operation {}` syntax. Only those responces that are declared neither by default, nor for a specific operation, will cause unexpected response behaviour.
|
data/docs/security.md
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
Use `security` declaration for the authorization schema. Inside the block you have access to 3 methods:
|
2
|
-
* `basic_auth`
|
3
|
-
* `token_auth`
|
4
|
-
* `key_auth`
|
5
|
-
|
6
|
-
## Basic Authentication
|
7
|
-
|
8
|
-
Use `basic_auth(login, password)` to define [basic authentication following RFC-7617][basic_auth]:
|
9
|
-
|
10
|
-
```ruby
|
11
|
-
operation :find_cat do |settings|
|
12
|
-
security do
|
13
|
-
basic_auth settings.login, settings.password
|
14
|
-
end
|
15
|
-
end
|
16
|
-
```
|
17
|
-
|
18
|
-
This declaration with add a header `"Authentication" => "Basic {encoded token}"` to every request. The header is added independenlty of declaration for other [headers][headers].
|
19
|
-
|
20
|
-
## Token Authentication
|
21
|
-
|
22
|
-
The command `token_auth(token, **options)` allows you to insert a customizable token to any part of the request. Unlike `basic_auth`, you need to provide the token (build, encrypt etc.) by hand.
|
23
|
-
|
24
|
-
```ruby
|
25
|
-
operation :find_cat do |settings|
|
26
|
-
security do
|
27
|
-
token_auth settings.token
|
28
|
-
end
|
29
|
-
end
|
30
|
-
```
|
31
|
-
|
32
|
-
By default the token is added to `"Authentication" => {token}` header of the request. You can prepend it with a necessary prefix. For example, you can define a [Bearer token authentication following RFC-6750][bearer]:
|
33
|
-
|
34
|
-
```ruby
|
35
|
-
operation :find_cat do |settings|
|
36
|
-
security do
|
37
|
-
token_auth settings.token, prefix: "Bearer"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
```
|
41
|
-
|
42
|
-
Instead of headers, you can send a token in either request body, or a query. In this case the token will be sent under `access_key` ignoring a prefix:
|
43
|
-
|
44
|
-
```ruby
|
45
|
-
operation :find_cat do |settings|
|
46
|
-
path { "/cats" }
|
47
|
-
security do
|
48
|
-
token_auth settings.token, using: :query
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# will send a request to "../cats?access_key={token}"
|
53
|
-
```
|
54
|
-
|
55
|
-
## Authentication Using Arbitrary Key
|
56
|
-
|
57
|
-
The most customizeable option is to authenticate requests with an arbitrary key. This time key-value pair will be added to the selected part (`headers`, `body`, or `query`) of the request:
|
58
|
-
|
59
|
-
```ruby
|
60
|
-
operation :find_cat do |settings|
|
61
|
-
path { "/cats" }
|
62
|
-
security do
|
63
|
-
key_auth :accss_key, settings.token, using: :query
|
64
|
-
end
|
65
|
-
end
|
66
|
-
```
|
67
|
-
|
68
|
-
## Authentication Using Several Schemes
|
69
|
-
|
70
|
-
You can define several schemes for the same request. All of them will be applied at once:
|
71
|
-
|
72
|
-
```ruby
|
73
|
-
operation :find_cat do |settings|
|
74
|
-
security do
|
75
|
-
basic_auth settings.login, settings.password
|
76
|
-
token_auth settings.token, using: :query
|
77
|
-
end
|
78
|
-
end
|
79
|
-
```
|
80
|
-
|
81
|
-
Moreover, you can declare shared authentication by default, and either update, or reload it for a specific operation:
|
82
|
-
|
83
|
-
```ruby
|
84
|
-
operation do |settings|
|
85
|
-
security { basic_auth settings.login, settings.password }
|
86
|
-
end
|
87
|
-
|
88
|
-
operation :find_cat do |settings|
|
89
|
-
security { token_auth settings.token, using: :query } # added to default security
|
90
|
-
end
|
91
|
-
|
92
|
-
operation :find_cats do |settings|
|
93
|
-
security { token_auth settings.token } # reloads default "Authentication" header
|
94
|
-
end
|
95
|
-
```
|
96
|
-
|
97
|
-
|
98
|
-
[basic_auth]: https://tools.ietf.org/html/rfc7617
|
99
|
-
[bearer]: https://tools.ietf.org/html/rfc6750
|
100
|
-
[headers]:
|
101
|
-
[body]:
|
102
|
-
[query]:
|
data/docs/settings.md
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
Use `settings` to parameterize an instance of the client.
|
2
|
-
|
3
|
-
Inside the block you can define both `param`s and `option`s for a client constructor. See [dry-initializer docs][dry-initializer] for detailed description of the methods' syntax.
|
4
|
-
|
5
|
-
```ruby
|
6
|
-
require "evil-client"
|
7
|
-
require "dry-types"
|
8
|
-
|
9
|
-
class CatsClient < Evil::Client
|
10
|
-
settings do
|
11
|
-
param :roor_url
|
12
|
-
option :version, type: Dry::Types["coercible.int"], default: proc { 1 }
|
13
|
-
option :login, type: Dry::Types["strict.string"] # required
|
14
|
-
option :password, type: Dry::Types["strict.string"] # required
|
15
|
-
end
|
16
|
-
end
|
17
|
-
```
|
18
|
-
|
19
|
-
Now you can initialize a client:
|
20
|
-
|
21
|
-
```ruby
|
22
|
-
client = CatsClient.new "https://cats.example.com",
|
23
|
-
login: "cats_lover",
|
24
|
-
password: "purr"
|
25
|
-
```
|
26
|
-
|
27
|
-
A container with assigned settings will be passed to blocks declaring [base_url][base_url], [connection][connection], and [operations][operation].
|
28
|
-
|
29
|
-
[base_url]:
|
30
|
-
[connection]:
|
31
|
-
[operation]:
|
32
|
-
[dry-initializer]: http://dry-rb.org/gems/dry-initializer
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require "net/http"
|
2
|
-
require "net/https"
|
3
|
-
|
4
|
-
class Evil::Client
|
5
|
-
class Connection
|
6
|
-
# Net::HTTP based implementation of [Evil::Client::Connection]
|
7
|
-
class NetHTTP < Connection
|
8
|
-
# Sends a request to the remote uri,
|
9
|
-
# and returns rack-compatible response
|
10
|
-
#
|
11
|
-
# @param [Hash] env Middleware environment with keys:
|
12
|
-
# :http_method, :path, :query_string, :body_string, :headers
|
13
|
-
# @return [Array] Rack-compatible response [status, body, headers]
|
14
|
-
#
|
15
|
-
def call(env, *)
|
16
|
-
request = build_request(env)
|
17
|
-
Net::HTTP.start base_uri.host, base_uri.port, opts do |http|
|
18
|
-
handle http.request(request)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def opts
|
25
|
-
@opts ||= {}.tap { |hash| hash[:use_ssl] = base_uri.scheme == "https" }
|
26
|
-
end
|
27
|
-
|
28
|
-
def build_request(env)
|
29
|
-
type, path, query, body, headers = parse_env(env)
|
30
|
-
|
31
|
-
sender = build_sender(type)
|
32
|
-
uri = build_uri(path, query)
|
33
|
-
|
34
|
-
sender.new(uri).tap do |request|
|
35
|
-
request.body = body
|
36
|
-
headers.each { |key, value| request[key] = value }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def parse_env(env)
|
41
|
-
env.values_at :http_method, :path, :query_string, :body_string, :headers
|
42
|
-
end
|
43
|
-
|
44
|
-
def build_sender(type)
|
45
|
-
Net::HTTP.const_get type.capitalize
|
46
|
-
end
|
47
|
-
|
48
|
-
def build_uri(path, query)
|
49
|
-
base_uri.merge(URI.encode(path)).tap { |uri| uri.query = query }
|
50
|
-
end
|
51
|
-
|
52
|
-
def handle(response)
|
53
|
-
[response.code.to_i, Hash(response.header), Array(response.body)]
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
data/lib/evil/client/dsl.rb
DELETED
@@ -1,127 +0,0 @@
|
|
1
|
-
class Evil::Client
|
2
|
-
# Defines a DSL to customize class-level settings of the specific client
|
3
|
-
module DSL
|
4
|
-
require_relative "dsl/base"
|
5
|
-
require_relative "dsl/files"
|
6
|
-
require_relative "dsl/headers"
|
7
|
-
require_relative "dsl/http_method"
|
8
|
-
require_relative "dsl/path"
|
9
|
-
require_relative "dsl/query"
|
10
|
-
require_relative "dsl/response"
|
11
|
-
require_relative "dsl/responses"
|
12
|
-
require_relative "dsl/security"
|
13
|
-
require_relative "dsl/verifier"
|
14
|
-
require_relative "dsl/operation"
|
15
|
-
require_relative "dsl/operations"
|
16
|
-
require_relative "dsl/scope"
|
17
|
-
|
18
|
-
# Adds [#operations] to a specific client's instances
|
19
|
-
def self.extended(klass)
|
20
|
-
klass.include Dry::Initializer.define -> do
|
21
|
-
param :settings
|
22
|
-
param :base_url
|
23
|
-
param :operations
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# Helper to define params and options a for a client's constructor
|
28
|
-
#
|
29
|
-
# @example
|
30
|
-
# class MyClient < Evil::Client
|
31
|
-
# end
|
32
|
-
#
|
33
|
-
# MyClient.new "https://foo.com", user: "bar", token: "baz"
|
34
|
-
#
|
35
|
-
# @param [Proc] block
|
36
|
-
# @return [self]
|
37
|
-
#
|
38
|
-
def settings(&block)
|
39
|
-
return self unless block
|
40
|
-
schema[:settings] = Class.new { include Dry::Initializer.define(&block) }
|
41
|
-
self
|
42
|
-
end
|
43
|
-
|
44
|
-
# Helper to define base url of the server
|
45
|
-
#
|
46
|
-
# @param [#to_s] value
|
47
|
-
# @return [self]
|
48
|
-
#
|
49
|
-
def base_url(&block)
|
50
|
-
return self unless block
|
51
|
-
schema[:base_url] = block
|
52
|
-
self
|
53
|
-
end
|
54
|
-
|
55
|
-
# Helper specify a connection to be used by a client
|
56
|
-
#
|
57
|
-
# @param [#to_sym] type (nil)
|
58
|
-
# The specific type of connection. Uses NetHTTP by default.
|
59
|
-
# @return [self]
|
60
|
-
#
|
61
|
-
def connection(type = nil, &block)
|
62
|
-
schema[:connection] = Connection[type]
|
63
|
-
schema[:middleware] = Middleware.new(&block)
|
64
|
-
self
|
65
|
-
end
|
66
|
-
|
67
|
-
# Helper to declare operation, either default or specific
|
68
|
-
#
|
69
|
-
# @param [#to_sym] name (nil)
|
70
|
-
# @param [Proc] block
|
71
|
-
# @return [self]
|
72
|
-
#
|
73
|
-
def operation(name = nil, &block)
|
74
|
-
schema[:operations].register(name, &block)
|
75
|
-
self
|
76
|
-
end
|
77
|
-
|
78
|
-
# Helper to define scopes of the client's top-level DSL
|
79
|
-
#
|
80
|
-
# @param [#to_sym] name (:[])
|
81
|
-
# @param [Proc] block
|
82
|
-
# @return [self]
|
83
|
-
#
|
84
|
-
def scope(name = :[], &block)
|
85
|
-
klass = Class.new(Scope, &block)
|
86
|
-
define_method(name) do |*args, **options|
|
87
|
-
klass.new(*args, __scope__: self, **options)
|
88
|
-
end
|
89
|
-
self
|
90
|
-
end
|
91
|
-
|
92
|
-
# Takes constructor arguments and builds a final schema for an instance
|
93
|
-
# (All the instantiation magics goes here)
|
94
|
-
#
|
95
|
-
# @param [Object] *args
|
96
|
-
# @return [Hash<Symbol, Object>]
|
97
|
-
#
|
98
|
-
def new(*args)
|
99
|
-
settings = schema[:settings].new(*args)
|
100
|
-
base_url = schema[:base_url].call(settings)
|
101
|
-
middleware = schema[:middleware].finalize(settings)
|
102
|
-
operations = schema[:operations].finalize(settings)
|
103
|
-
client = schema[:connection].new URI(base_url)
|
104
|
-
connection = Middleware.prepend.(middleware.(Middleware.append.(client)))
|
105
|
-
|
106
|
-
data = operations.each_with_object({}) do |(key, schema), hash|
|
107
|
-
hash[key] = Evil::Client::Operation.new schema, connection
|
108
|
-
end
|
109
|
-
|
110
|
-
super(settings, base_url, data)
|
111
|
-
end
|
112
|
-
|
113
|
-
private
|
114
|
-
|
115
|
-
BASE_URL = proc { raise NotImplementedError.new "Base url is not defined" }
|
116
|
-
|
117
|
-
def schema
|
118
|
-
@schema ||= {
|
119
|
-
settings: Class.new,
|
120
|
-
base_url: BASE_URL,
|
121
|
-
connection: Connection[nil],
|
122
|
-
middleware: Middleware.new,
|
123
|
-
operations: Operations.new
|
124
|
-
}
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
data/lib/evil/client/dsl/base.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module Evil::Client::DSL
|
2
|
-
class Base
|
3
|
-
def self.[](schema, *args, &block)
|
4
|
-
new(*args, &block).call(schema)
|
5
|
-
end
|
6
|
-
|
7
|
-
def call(schema)
|
8
|
-
schema
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def merge(source, target)
|
14
|
-
target.inject(source) do |obj, (key, val)|
|
15
|
-
obj.merge key => (Hash === val ? merge(obj.fetch(key, {}), val) : val)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def coercer
|
20
|
-
@coercer ||= if @model && @block then Class.new(@model, &@block)
|
21
|
-
elsif @block then Class.new(Evil::Struct, &@block)
|
22
|
-
elsif @model then @model
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
module Evil::Client::DSL
|
2
|
-
# Nested definition for attached files
|
3
|
-
class Files
|
4
|
-
# Builds a final upload schema from request options
|
5
|
-
#
|
6
|
-
# @param [Hash<Symbol, Object>] options
|
7
|
-
# @return [Hash<Symbol, Object>]
|
8
|
-
#
|
9
|
-
def call(**options)
|
10
|
-
@mutex.synchronize do
|
11
|
-
@schema = []
|
12
|
-
instance_exec(options, &@block)
|
13
|
-
@schema
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def initialize(&block)
|
20
|
-
@mutex = Mutex.new
|
21
|
-
@block = block
|
22
|
-
end
|
23
|
-
|
24
|
-
# ==========================================================================
|
25
|
-
# Helper methods that mutate files @schema
|
26
|
-
# ==========================================================================
|
27
|
-
|
28
|
-
def add(data, type: "text/plain", charset: "utf-8", filename: nil, **)
|
29
|
-
@schema << {
|
30
|
-
file: data.respond_to?(:read) ? data : StringIO.new(data),
|
31
|
-
type: MIME::Types[type].first,
|
32
|
-
charset: charset,
|
33
|
-
filename: filename
|
34
|
-
}
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|