haveapi-client 0.20.0 → 0.21.1
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 +4 -4
- data/Gemfile +5 -0
- data/Rakefile +0 -1
- data/haveapi-client.gemspec +7 -10
- data/lib/haveapi/cli/action_state.rb +50 -51
- data/lib/haveapi/cli/authentication/base.rb +4 -9
- data/lib/haveapi/cli/authentication/basic.rb +3 -1
- data/lib/haveapi/cli/authentication/token.rb +7 -8
- data/lib/haveapi/cli/cli.rb +115 -127
- data/lib/haveapi/cli/command.rb +2 -4
- data/lib/haveapi/cli/commands/action_state_wait.rb +9 -9
- data/lib/haveapi/cli/example_formatter.rb +8 -8
- data/lib/haveapi/cli/output_formatter.rb +39 -36
- data/lib/haveapi/cli/utils.rb +5 -5
- data/lib/haveapi/cli.rb +1 -1
- data/lib/haveapi/client/action.rb +17 -20
- data/lib/haveapi/client/action_state.rb +3 -7
- data/lib/haveapi/client/authentication/base.rb +4 -7
- data/lib/haveapi/client/authentication/basic.rb +2 -2
- data/lib/haveapi/client/authentication/noauth.rb +0 -1
- data/lib/haveapi/client/authentication/token.rb +28 -27
- data/lib/haveapi/client/client.rb +12 -6
- data/lib/haveapi/client/communicator.rb +33 -35
- data/lib/haveapi/client/exceptions.rb +5 -9
- data/lib/haveapi/client/parameters/resource.rb +1 -0
- data/lib/haveapi/client/parameters/typed.rb +3 -5
- data/lib/haveapi/client/params.rb +8 -8
- data/lib/haveapi/client/resource.rb +12 -13
- data/lib/haveapi/client/resource_instance.rb +71 -72
- data/lib/haveapi/client/resource_instance_list.rb +2 -1
- data/lib/haveapi/client/response.rb +8 -8
- data/lib/haveapi/client/validator.rb +7 -8
- data/lib/haveapi/client/validators/confirmation.rb +1 -0
- data/lib/haveapi/client/validators/length.rb +1 -0
- data/lib/haveapi/client/validators/numericality.rb +2 -1
- data/lib/haveapi/client/validators/presence.rb +1 -0
- data/lib/haveapi/client/version.rb +2 -2
- data/lib/haveapi/client.rb +2 -2
- data/lib/restclient_ext/resource.rb +5 -5
- data/shell.nix +1 -1
- metadata +15 -43
@@ -34,10 +34,12 @@ module HaveAPI::Client
|
|
34
34
|
# @return [:imperfect] if minor version differs
|
35
35
|
# @return [false] if not compatible
|
36
36
|
def compatible?
|
37
|
-
description_for(path_for, {describe: :versions})
|
38
|
-
@proto_version == HaveAPI::Client::PROTOCOL_VERSION
|
39
|
-
|
40
|
-
|
37
|
+
description_for(path_for, { describe: :versions })
|
38
|
+
if @proto_version == HaveAPI::Client::PROTOCOL_VERSION
|
39
|
+
:compatible
|
40
|
+
else
|
41
|
+
:imperfect
|
42
|
+
end
|
41
43
|
rescue ProtocolError
|
42
44
|
false
|
43
45
|
end
|
@@ -45,14 +47,14 @@ module HaveAPI::Client
|
|
45
47
|
# Authenticate user with selected +auth_method+.
|
46
48
|
# +auth_method+ is a name of registered authentication provider.
|
47
49
|
# +options+ are specific for each authentication provider.
|
48
|
-
def authenticate(auth_method, options = {}, &
|
50
|
+
def authenticate(auth_method, options = {}, &)
|
49
51
|
desc = describe_api(@version)
|
50
52
|
|
51
53
|
@auth = self.class.auth_methods[auth_method].new(
|
52
54
|
self,
|
53
55
|
desc[:authentication][auth_method],
|
54
56
|
options,
|
55
|
-
&
|
57
|
+
&
|
56
58
|
)
|
57
59
|
@rest = @auth.resource || @rest
|
58
60
|
end
|
@@ -62,11 +64,11 @@ module HaveAPI::Client
|
|
62
64
|
end
|
63
65
|
|
64
66
|
def available_versions
|
65
|
-
description_for(path_for, {describe: :versions})
|
67
|
+
description_for(path_for, { describe: :versions })
|
66
68
|
end
|
67
69
|
|
68
|
-
def describe_api(v=nil)
|
69
|
-
description_for(path_for(v), v.nil? ? {describe: :default} : {})
|
70
|
+
def describe_api(v = nil)
|
71
|
+
description_for(path_for(v), v.nil? ? { describe: :default } : {})
|
70
72
|
end
|
71
73
|
|
72
74
|
def describe_resource(path)
|
@@ -97,7 +99,7 @@ module HaveAPI::Client
|
|
97
99
|
a = tmp[:actions][action]
|
98
100
|
|
99
101
|
unless a # search in aliases
|
100
|
-
|
102
|
+
tmp[:actions].each_value do |v|
|
101
103
|
if v[:aliases].include?(action.to_s)
|
102
104
|
a = v
|
103
105
|
break
|
@@ -124,43 +126,39 @@ module HaveAPI::Client
|
|
124
126
|
params.delete(:meta)
|
125
127
|
end
|
126
128
|
|
127
|
-
if %w
|
129
|
+
if %w[POST PUT].include?(action.http_method)
|
128
130
|
ns = {}
|
129
131
|
ns[input_namespace] = params if input_namespace
|
130
132
|
ns[:_meta] = meta if meta
|
131
133
|
ns.update(@auth.request_payload)
|
132
134
|
|
133
135
|
args << ns.to_json
|
134
|
-
args << {content_type: :json, accept: :json, user_agent: @identity}.update(@auth.request_headers)
|
136
|
+
args << { content_type: :json, accept: :json, user_agent: @identity }.update(@auth.request_headers)
|
135
137
|
|
136
|
-
elsif %w
|
138
|
+
elsif %w[GET DELETE].include?(action.http_method)
|
137
139
|
get_params = {}
|
138
140
|
|
139
141
|
params.each do |k, v|
|
140
142
|
get_params["#{input_namespace}[#{k}]"] = v
|
141
143
|
end
|
142
144
|
|
143
|
-
meta
|
144
|
-
|
145
|
-
|
146
|
-
|
145
|
+
if meta
|
146
|
+
meta.each do |k, v|
|
147
|
+
get_params["_meta[#{k}]"] = v # FIXME: read _meta namespace from the description
|
148
|
+
end
|
149
|
+
end
|
147
150
|
|
148
|
-
args << {params: get_params.update(@auth.request_query_params), accept: :json, user_agent: @identity}.update(@auth.request_headers)
|
151
|
+
args << { params: get_params.update(@auth.request_query_params), accept: :json, user_agent: @identity }.update(@auth.request_headers)
|
149
152
|
end
|
150
153
|
|
151
154
|
begin
|
152
155
|
response = parse(@rest[action.prepared_path].method(action.http_method.downcase.to_sym).call(*args))
|
153
|
-
|
154
156
|
rescue RestClient::Forbidden
|
155
157
|
return error('Access forbidden. Bad user name or password? Not authorized?')
|
156
|
-
|
157
|
-
|
158
|
-
response = parse(e.http_body)
|
159
|
-
|
160
|
-
rescue RestClient::BadRequest => e
|
158
|
+
rescue RestClient::ResourceNotFound,
|
159
|
+
RestClient::BadRequest => e
|
161
160
|
response = parse(e.http_body)
|
162
|
-
|
163
|
-
rescue => e
|
161
|
+
rescue StandardError => e
|
164
162
|
return error("Fatal API error: #{e.inspect}")
|
165
163
|
end
|
166
164
|
|
@@ -177,15 +175,16 @@ module HaveAPI::Client
|
|
177
175
|
end
|
178
176
|
|
179
177
|
private
|
178
|
+
|
180
179
|
def ok(response)
|
181
|
-
{status: true, response:
|
180
|
+
{ status: true, response: }
|
182
181
|
end
|
183
182
|
|
184
|
-
def error(msg, errors={})
|
185
|
-
{status: false, message: msg, errors:
|
183
|
+
def error(msg, errors = {})
|
184
|
+
{ status: false, message: msg, errors: }
|
186
185
|
end
|
187
186
|
|
188
|
-
def path_for(v=nil, r=nil)
|
187
|
+
def path_for(v = nil, r = nil)
|
189
188
|
ret = '/'
|
190
189
|
|
191
190
|
ret += "v#{v}/" if v
|
@@ -194,7 +193,7 @@ module HaveAPI::Client
|
|
194
193
|
ret
|
195
194
|
end
|
196
195
|
|
197
|
-
def description_for(path, query_params={})
|
196
|
+
def description_for(path, query_params = {})
|
198
197
|
ret = parse(@rest[path].get_options({
|
199
198
|
params: @auth.request_payload.update(@auth.request_query_params).update(query_params),
|
200
199
|
user_agent: @identity
|
@@ -206,8 +205,7 @@ module HaveAPI::Client
|
|
206
205
|
|
207
206
|
unless ret[:version]
|
208
207
|
raise ProtocolError,
|
209
|
-
|
210
|
-
"while the API server uses an unspecified version (pre 1.0)"
|
208
|
+
"Incompatible protocol version: the client uses v#{p_v} while the API server uses an unspecified version (pre 1.0)"
|
211
209
|
end
|
212
210
|
|
213
211
|
major1, minor1 = ret[:version].split('.')
|
@@ -215,8 +213,8 @@ module HaveAPI::Client
|
|
215
213
|
|
216
214
|
if major1 != major2
|
217
215
|
raise ProtocolError,
|
218
|
-
|
219
|
-
|
216
|
+
"Incompatible protocol version: the client uses v#{p_v} " \
|
217
|
+
"while the API server uses v#{ret[:version]}"
|
220
218
|
end
|
221
219
|
|
222
220
|
warn "The client uses protocol v#{p_v} while the API server uses v#{ret[:version]}"
|
@@ -1,15 +1,13 @@
|
|
1
1
|
module HaveAPI::Client
|
2
|
-
class ProtocolError < StandardError
|
2
|
+
class ProtocolError < StandardError; end
|
3
3
|
|
4
4
|
class ActionFailed < StandardError
|
5
5
|
attr_reader :response
|
6
6
|
|
7
7
|
def initialize(response)
|
8
|
-
|
9
|
-
end
|
8
|
+
super("#{response.action.name} failed: #{response.message}")
|
10
9
|
|
11
|
-
|
12
|
-
"#{@response.action.name} failed: #{@response.message}"
|
10
|
+
@response = response
|
13
11
|
end
|
14
12
|
end
|
15
13
|
|
@@ -17,12 +15,10 @@ module HaveAPI::Client
|
|
17
15
|
attr_reader :errors
|
18
16
|
|
19
17
|
def initialize(action, errors)
|
18
|
+
super("#{action.name} failed: input parameters not valid")
|
19
|
+
|
20
20
|
@action = action
|
21
21
|
@errors = errors
|
22
22
|
end
|
23
|
-
|
24
|
-
def message
|
25
|
-
"#{@action.name} failed: input parameters not valid"
|
26
|
-
end
|
27
23
|
end
|
28
24
|
end
|
@@ -40,10 +40,11 @@ module HaveAPI::Client
|
|
40
40
|
end
|
41
41
|
|
42
42
|
protected
|
43
|
+
|
43
44
|
def coerce(raw)
|
44
45
|
type = @desc[:type]
|
45
46
|
|
46
|
-
|
47
|
+
if type == 'Integer'
|
47
48
|
raw.to_i
|
48
49
|
|
49
50
|
elsif type == 'Float'
|
@@ -62,21 +63,18 @@ module HaveAPI::Client
|
|
62
63
|
else
|
63
64
|
begin
|
64
65
|
DateTime.iso8601(raw).to_time
|
65
|
-
|
66
66
|
rescue ArgumentError
|
67
67
|
@errors << 'not in ISO 8601 format'
|
68
68
|
nil
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
elsif %w
|
72
|
+
elsif %w[String Text].include?(type)
|
73
73
|
raw.to_s
|
74
74
|
|
75
75
|
else
|
76
76
|
raw
|
77
77
|
end
|
78
|
-
|
79
|
-
val
|
80
78
|
end
|
81
79
|
end
|
82
80
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module HaveAPI::Client
|
2
|
-
module Parameters
|
2
|
+
module Parameters; end
|
3
3
|
|
4
4
|
class Params
|
5
5
|
attr_reader :errors, :params
|
@@ -16,12 +16,12 @@ module HaveAPI::Client
|
|
16
16
|
@action.input_params.each do |name, p|
|
17
17
|
next unless @data.has_key?(name)
|
18
18
|
|
19
|
-
if p[:type] == 'Resource'
|
20
|
-
|
19
|
+
@params[name] = if p[:type] == 'Resource'
|
20
|
+
Parameters::Resource.new(self, p, @data[name])
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
else
|
23
|
+
Parameters::Typed.new(self, p, @data[name])
|
24
|
+
end
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -36,10 +36,9 @@ module HaveAPI::Client
|
|
36
36
|
next
|
37
37
|
end
|
38
38
|
|
39
|
-
|
39
|
+
unless @params[name].valid?
|
40
40
|
error(name, @params[name].errors)
|
41
41
|
end
|
42
|
-
|
43
42
|
end
|
44
43
|
|
45
44
|
@errors.empty?
|
@@ -58,6 +57,7 @@ module HaveAPI::Client
|
|
58
57
|
end
|
59
58
|
|
60
59
|
protected
|
60
|
+
|
61
61
|
def error(param, msg)
|
62
62
|
@errors[param] ||= []
|
63
63
|
|
@@ -71,6 +71,7 @@ module HaveAPI::Client
|
|
71
71
|
end
|
72
72
|
|
73
73
|
protected
|
74
|
+
|
74
75
|
# Define access/write methods for action +action+.
|
75
76
|
def define_action(action)
|
76
77
|
action.aliases(true).each do |name|
|
@@ -116,7 +117,7 @@ module HaveAPI::Client
|
|
116
117
|
if user_params.has_key?(:meta)
|
117
118
|
meta = user_params[:meta]
|
118
119
|
|
119
|
-
%i
|
120
|
+
%i[block block_interval block_timeout].each do |p|
|
120
121
|
client_opts[p] = meta.delete(p) if meta.has_key?(p)
|
121
122
|
end
|
122
123
|
end
|
@@ -126,21 +127,18 @@ module HaveAPI::Client
|
|
126
127
|
|
127
128
|
ret = Response.new(action, action.execute(input_params))
|
128
129
|
|
129
|
-
raise ActionFailed
|
130
|
+
raise ActionFailed, ret unless ret.ok?
|
130
131
|
|
131
132
|
return_value = case action.output && action.output_layout
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
when :object_list
|
136
|
-
ResourceInstanceList.new(@client, @api, self, action, ret)
|
133
|
+
when :object
|
134
|
+
ResourceInstance.new(@client, @api, self, action:, response: ret)
|
137
135
|
|
138
|
-
|
139
|
-
|
136
|
+
when :object_list
|
137
|
+
ResourceInstanceList.new(@client, @api, self, action, ret)
|
140
138
|
|
141
|
-
|
142
|
-
|
143
|
-
|
139
|
+
else # :hash, :hash_list
|
140
|
+
ret
|
141
|
+
end
|
144
142
|
|
145
143
|
if action.blocking? && client_opts[:block]
|
146
144
|
wait_opts = {}
|
@@ -165,7 +163,8 @@ module HaveAPI::Client
|
|
165
163
|
# Called before defining a method named +name+ that will
|
166
164
|
# invoke +action+.
|
167
165
|
def define_method?(action, name)
|
168
|
-
return false if %i
|
166
|
+
return false if %i[new].include?(name.to_sym)
|
167
|
+
|
169
168
|
true
|
170
169
|
end
|
171
170
|
|
@@ -24,28 +24,28 @@ module HaveAPI::Client
|
|
24
24
|
if response.is_a?(Hash)
|
25
25
|
@params = response
|
26
26
|
@prepared_args = response[:_meta][:path_params]
|
27
|
-
@meta
|
27
|
+
@meta ||= response[:_meta]
|
28
28
|
|
29
29
|
else
|
30
30
|
@response = response
|
31
31
|
@params = response.response
|
32
32
|
@prepared_args = response.meta[:path_params]
|
33
|
-
@meta
|
33
|
+
@meta ||= response.meta
|
34
34
|
end
|
35
35
|
|
36
36
|
setup_from_clone(resource)
|
37
37
|
define_attributes
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
return if @persistent
|
41
|
+
|
42
|
+
setup_from_clone(resource)
|
43
|
+
define_implicit_attributes
|
44
|
+
define_attributes(@action.input_params)
|
45
45
|
end
|
46
46
|
|
47
47
|
def new
|
48
|
-
raise NoMethodError
|
48
|
+
raise NoMethodError
|
49
49
|
end
|
50
50
|
|
51
51
|
# Invoke +create+ action if the object is not persistent,
|
@@ -58,13 +58,10 @@ module HaveAPI::Client
|
|
58
58
|
@action.provide_args
|
59
59
|
@response = Response.new(@action, @action.execute(attributes_for_api(@action)))
|
60
60
|
|
61
|
-
|
62
|
-
@params = @response.response
|
63
|
-
define_attributes
|
61
|
+
return nil unless @response.ok?
|
64
62
|
|
65
|
-
|
66
|
-
|
67
|
-
end
|
63
|
+
@params = @response.response
|
64
|
+
define_attributes
|
68
65
|
|
69
66
|
@persistent = true
|
70
67
|
self
|
@@ -73,7 +70,8 @@ module HaveAPI::Client
|
|
73
70
|
|
74
71
|
# Call #save and raise ActionFailed if it fails.
|
75
72
|
def save!
|
76
|
-
raise ActionFailed
|
73
|
+
raise ActionFailed, @response if save.nil?
|
74
|
+
|
77
75
|
self
|
78
76
|
end
|
79
77
|
|
@@ -104,68 +102,69 @@ module HaveAPI::Client
|
|
104
102
|
end
|
105
103
|
|
106
104
|
def to_s
|
107
|
-
"<#{self.class
|
105
|
+
"<#{self.class}:#{object_id}:#{@resource._name}>"
|
108
106
|
end
|
109
107
|
|
110
108
|
protected
|
109
|
+
|
111
110
|
# Define access/writer methods for object attributes.
|
112
111
|
def define_attributes(params = nil)
|
113
112
|
(params || @action.params).each do |name, param|
|
114
113
|
case param[:type]
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
},
|
114
|
+
when 'Resource'
|
115
|
+
@resource_instances[name] = find_association(param, @params[name])
|
116
|
+
|
117
|
+
# id reader
|
118
|
+
ensure_method(:"#{name}_id") do
|
119
|
+
@params[name] && @params[name][ param[:value_id].to_sym ]
|
120
|
+
end
|
121
|
+
|
122
|
+
# id writer
|
123
|
+
ensure_method(:"#{name}_id=") do |id|
|
124
|
+
@params[name] ||= {}
|
125
|
+
@params[name][ param[:value_id].to_sym ] = id
|
126
|
+
|
127
|
+
@resource_instances[name] = find_association(
|
128
|
+
param,
|
129
|
+
{
|
130
|
+
param[:value_id] => id,
|
131
|
+
:_meta => {
|
132
|
+
resolved: false,
|
133
|
+
# TODO: this will not work for nested resources, as they have
|
134
|
+
# multiple IDs
|
135
|
+
path_params: [id]
|
138
136
|
}
|
139
|
-
|
140
|
-
|
137
|
+
}
|
138
|
+
)
|
139
|
+
end
|
141
140
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
141
|
+
# value reader
|
142
|
+
ensure_method(name) do
|
143
|
+
@resource_instances[name] && @resource_instances[name].resolve
|
144
|
+
end
|
146
145
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
146
|
+
# value writer
|
147
|
+
ensure_method(:"#{name}=") do |obj|
|
148
|
+
@params[name] ||= {}
|
149
|
+
@params[name][ param[:value_id].to_sym ] = obj.method(param[:value_id]).call
|
150
|
+
@params[name][ param[:value_label].to_sym ] = obj.method(param[:value_label]).call
|
152
151
|
|
153
|
-
|
154
|
-
|
152
|
+
@resource_instances[name] = obj
|
153
|
+
end
|
155
154
|
|
156
|
-
|
157
|
-
|
158
|
-
|
155
|
+
else
|
156
|
+
# reader
|
157
|
+
ensure_method(name) { @params[name] }
|
159
158
|
|
160
|
-
|
161
|
-
|
159
|
+
# writer
|
160
|
+
ensure_method(:"#{name}=") { |new_val| @params[name] = new_val }
|
162
161
|
end
|
163
162
|
end
|
164
163
|
end
|
165
164
|
|
166
165
|
# Define method +name+ with +block+ if it isn't defined yet.
|
167
|
-
def ensure_method(name, &
|
168
|
-
define_singleton_method(name, &
|
166
|
+
def ensure_method(name, &)
|
167
|
+
define_singleton_method(name, &) unless respond_to?(name)
|
169
168
|
end
|
170
169
|
|
171
170
|
# Define nil references to resource attributes.
|
@@ -185,13 +184,13 @@ module HaveAPI::Client
|
|
185
184
|
return ret if action.input_layout != :object
|
186
185
|
|
187
186
|
action.input_params.each do |name, param|
|
188
|
-
case param[:type]
|
189
|
-
|
190
|
-
|
187
|
+
ret[name] = case param[:type]
|
188
|
+
when 'Resource'
|
189
|
+
@params[name][ param[:value_id].to_sym ]
|
191
190
|
|
192
|
-
|
193
|
-
|
194
|
-
|
191
|
+
else
|
192
|
+
@params[name]
|
193
|
+
end
|
195
194
|
end
|
196
195
|
|
197
196
|
ret
|
@@ -209,13 +208,13 @@ module HaveAPI::Client
|
|
209
208
|
|
210
209
|
# FIXME: read _meta namespace from description
|
211
210
|
ResourceInstance.new(
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
211
|
+
@client,
|
212
|
+
@api,
|
213
|
+
tmp,
|
214
|
+
action: tmp.actions[:show],
|
215
|
+
resolved: res_val[:_meta][:resolved],
|
216
|
+
response: res_val[:_meta][:resolved] ? res_val : nil,
|
217
|
+
meta: res_val[:_meta]
|
219
218
|
)
|
220
219
|
end
|
221
220
|
|
@@ -2,10 +2,11 @@ module HaveAPI::Client
|
|
2
2
|
# A list of ResourceInstance objects.
|
3
3
|
class ResourceInstanceList < Array
|
4
4
|
def initialize(client, api, resource, action, response)
|
5
|
+
super()
|
5
6
|
@response = response
|
6
7
|
|
7
8
|
response.response.each do |hash|
|
8
|
-
self << ResourceInstance.new(client, api, resource, action
|
9
|
+
self << ResourceInstance.new(client, api, resource, action:, response: hash)
|
9
10
|
end
|
10
11
|
end
|
11
12
|
|
@@ -19,10 +19,10 @@ class HaveAPI::Client::Response
|
|
19
19
|
|
20
20
|
def response
|
21
21
|
case @action.output_layout
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
when :object, :object_list, :hash, :hash_list
|
23
|
+
@response[:response][@action.namespace(:output).to_sym]
|
24
|
+
else
|
25
|
+
@response[:response]
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -44,7 +44,7 @@ class HaveAPI::Client::Response
|
|
44
44
|
|
45
45
|
# Access namespaced params directly.
|
46
46
|
def [](key)
|
47
|
-
return unless %i
|
47
|
+
return unless %i[object hash].include?(@action.output_layout.to_sym)
|
48
48
|
|
49
49
|
@response[:response][@action.namespace(:output).to_sym][key]
|
50
50
|
end
|
@@ -52,7 +52,7 @@ class HaveAPI::Client::Response
|
|
52
52
|
# Iterate over namespaced items directly. Works for only for
|
53
53
|
# object_list or hash_list.
|
54
54
|
def each
|
55
|
-
return unless %i
|
55
|
+
return unless %i[list].include?(@action.layout.to_sym)
|
56
56
|
|
57
57
|
@response[:response][@action.namespace(:output).to_sym].each
|
58
58
|
end
|
@@ -61,10 +61,10 @@ class HaveAPI::Client::Response
|
|
61
61
|
# it is regularly called with the action's state.
|
62
62
|
#
|
63
63
|
# @see HaveAPI::Client::Action#wait_for_completion
|
64
|
-
def wait_for_completion(
|
64
|
+
def wait_for_completion(**, &)
|
65
65
|
id = meta[:action_state_id]
|
66
66
|
return nil unless id
|
67
67
|
|
68
|
-
HaveAPI::Client::Action.wait_for_completion(@action.client, id,
|
68
|
+
HaveAPI::Client::Action.wait_for_completion(@action.client, id, **, &)
|
69
69
|
end
|
70
70
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module HaveAPI::Client
|
2
|
-
module Validators
|
2
|
+
module Validators; end
|
3
3
|
|
4
4
|
class Validator
|
5
5
|
class << self
|
6
6
|
def name(v)
|
7
7
|
Validator.register(v, self)
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def register(name, klass)
|
11
11
|
@validators ||= {}
|
12
12
|
@validators[name] = klass
|
@@ -14,9 +14,9 @@ module HaveAPI::Client
|
|
14
14
|
|
15
15
|
def validate(validators, param, other_params)
|
16
16
|
ret = []
|
17
|
-
|
17
|
+
|
18
18
|
validators.each do |name, desc|
|
19
|
-
|
19
|
+
raise "unsupported validator '#{name}'" if @validators[name].nil?
|
20
20
|
|
21
21
|
v = @validators[name].new(desc, param, other_params)
|
22
22
|
ret.concat(v.errors) unless v.valid?
|
@@ -35,7 +35,7 @@ module HaveAPI::Client
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def errors
|
38
|
-
@errors || [opts[:message]
|
38
|
+
@errors || [format(opts[:message], value:)]
|
39
39
|
end
|
40
40
|
|
41
41
|
def valid?
|
@@ -43,9 +43,8 @@ module HaveAPI::Client
|
|
43
43
|
end
|
44
44
|
|
45
45
|
protected
|
46
|
-
|
47
|
-
|
48
|
-
end
|
46
|
+
|
47
|
+
attr_reader :opts
|
49
48
|
|
50
49
|
def error(e)
|
51
50
|
@errors ||= []
|