haveapi 0.20.0 → 0.21.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Rakefile +6 -6
- data/haveapi.gemspec +13 -13
- data/lib/haveapi/action.rb +153 -167
- data/lib/haveapi/action_state.rb +2 -6
- data/lib/haveapi/actions/default.rb +8 -10
- data/lib/haveapi/api.rb +2 -1
- data/lib/haveapi/authentication/base.rb +5 -8
- data/lib/haveapi/authentication/basic/provider.rb +4 -5
- data/lib/haveapi/authentication/chain.rb +19 -17
- data/lib/haveapi/authentication/oauth2/config.rb +12 -32
- data/lib/haveapi/authentication/oauth2/provider.rb +20 -30
- data/lib/haveapi/authentication/oauth2/revoke_endpoint.rb +1 -2
- data/lib/haveapi/authentication/token/action_config.rb +5 -3
- data/lib/haveapi/authentication/token/config.rb +5 -5
- data/lib/haveapi/authentication/token/provider.rb +33 -37
- data/lib/haveapi/authorization.rb +10 -4
- data/lib/haveapi/client_example.rb +11 -14
- data/lib/haveapi/client_examples/curl.rb +37 -37
- data/lib/haveapi/client_examples/fs_client.rb +29 -31
- data/lib/haveapi/client_examples/http.rb +35 -36
- data/lib/haveapi/client_examples/js_client.rb +62 -63
- data/lib/haveapi/client_examples/php_client.rb +77 -76
- data/lib/haveapi/client_examples/ruby_cli.rb +30 -30
- data/lib/haveapi/client_examples/ruby_client.rb +26 -26
- data/lib/haveapi/common.rb +3 -4
- data/lib/haveapi/context.rb +11 -10
- data/lib/haveapi/example.rb +9 -4
- data/lib/haveapi/example_list.rb +2 -2
- data/lib/haveapi/exceptions.rb +1 -1
- data/lib/haveapi/extensions/action_exceptions.rb +2 -2
- data/lib/haveapi/extensions/base.rb +1 -3
- data/lib/haveapi/extensions/exception_mailer.rb +260 -257
- data/lib/haveapi/hooks.rb +40 -39
- data/lib/haveapi/metadata.rb +1 -1
- data/lib/haveapi/model_adapter.rb +16 -27
- data/lib/haveapi/model_adapters/active_record.rb +59 -69
- data/lib/haveapi/output_formatter.rb +7 -7
- data/lib/haveapi/output_formatters/base.rb +2 -4
- data/lib/haveapi/parameters/resource.rb +7 -7
- data/lib/haveapi/parameters/typed.rb +6 -9
- data/lib/haveapi/params.rb +38 -45
- data/lib/haveapi/resource.rb +8 -8
- data/lib/haveapi/resources/action_state.rb +11 -19
- data/lib/haveapi/server.rb +102 -107
- data/lib/haveapi/spec/api_response.rb +1 -1
- data/lib/haveapi/spec/helpers.rb +1 -1
- data/lib/haveapi/spec/mock_action.rb +11 -10
- data/lib/haveapi/spec/spec_methods.rb +9 -8
- data/lib/haveapi/tasks/yard.rb +2 -2
- data/lib/haveapi/types.rb +0 -3
- data/lib/haveapi/validator.rb +6 -3
- data/lib/haveapi/validator_chain.rb +9 -8
- data/lib/haveapi/validators/acceptance.rb +6 -6
- data/lib/haveapi/validators/confirmation.rb +2 -3
- data/lib/haveapi/validators/exclusion.rb +1 -1
- data/lib/haveapi/validators/format.rb +1 -1
- data/lib/haveapi/validators/inclusion.rb +1 -1
- data/lib/haveapi/validators/length.rb +12 -11
- data/lib/haveapi/validators/numericality.rb +14 -13
- data/lib/haveapi/validators/presence.rb +4 -3
- data/lib/haveapi/version.rb +2 -2
- data/lib/haveapi.rb +2 -3
- data/spec/.rubocop.yml +4 -0
- data/spec/action/dsl_spec.rb +18 -18
- data/spec/authorization_spec.rb +8 -8
- data/spec/common_spec.rb +2 -1
- data/spec/documentation_spec.rb +2 -9
- data/spec/envelope_spec.rb +2 -2
- data/spec/hooks_spec.rb +12 -12
- data/spec/parameters/typed_spec.rb +6 -6
- data/spec/params_spec.rb +22 -24
- data/spec/resource_spec.rb +5 -7
- data/spec/spec_helper.rb +0 -1
- data/spec/validators/acceptance_spec.rb +1 -1
- data/spec/validators/confirmation_spec.rb +5 -5
- data/spec/validators/exclusion_spec.rb +3 -3
- data/spec/validators/format_spec.rb +2 -2
- data/spec/validators/inclusion_spec.rb +4 -4
- data/spec/validators/length_spec.rb +23 -23
- data/spec/validators/numericality_spec.rb +13 -13
- data/spec/validators/presence_spec.rb +3 -3
- metadata +49 -48
@@ -7,77 +7,77 @@ module HaveAPI::ClientExamples
|
|
7
7
|
order 20
|
8
8
|
|
9
9
|
def init
|
10
|
-
|
11
|
-
$api = new \\HaveAPI\\Client("#{base_url}", "#{version}");
|
12
|
-
END
|
10
|
+
<<~END
|
11
|
+
$api = new \\HaveAPI\\Client("#{base_url}", "#{version}");
|
12
|
+
END
|
13
13
|
end
|
14
14
|
|
15
15
|
def auth(method, desc)
|
16
16
|
case method
|
17
17
|
when :basic
|
18
|
-
|
19
|
-
#{init}
|
18
|
+
<<~END
|
19
|
+
#{init}
|
20
20
|
|
21
|
-
$api->authenticate("basic", ["user" => "user", "password" => "secret"]);
|
22
|
-
END
|
21
|
+
$api->authenticate("basic", ["user" => "user", "password" => "secret"]);
|
22
|
+
END
|
23
23
|
|
24
24
|
when :token
|
25
|
-
|
26
|
-
#{init}
|
25
|
+
<<~END
|
26
|
+
#{init}
|
27
27
|
|
28
|
-
// Get token using username and password
|
29
|
-
$api->authenticate("token", [#{auth_token_credentials(desc).map { |k, v| "\"#{k}\" => \"#{v}\"" }.join(', ')}]);
|
28
|
+
// Get token using username and password
|
29
|
+
$api->authenticate("token", [#{auth_token_credentials(desc).map { |k, v| "\"#{k}\" => \"#{v}\"" }.join(', ')}]);
|
30
30
|
|
31
|
-
echo "Token = ".$api->getAuthenticationProvider()->getToken();
|
31
|
+
echo "Token = ".$api->getAuthenticationProvider()->getToken();
|
32
32
|
|
33
|
-
// Next time, the client can authenticate using the token directly
|
34
|
-
$api->authenticate("token", ["token" => $savedToken]);
|
35
|
-
END
|
33
|
+
// Next time, the client can authenticate using the token directly
|
34
|
+
$api->authenticate("token", ["token" => $savedToken]);
|
35
|
+
END
|
36
36
|
|
37
37
|
when :oauth2
|
38
|
-
|
39
|
-
// OAuth2 requires session
|
40
|
-
session_start();
|
41
|
-
|
42
|
-
// Client instance
|
43
|
-
#{init}
|
44
|
-
// Check if we already have an access token
|
45
|
-
if (isset($_SESSION["access_token"])) {
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
} else {
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
}
|
80
|
-
END
|
38
|
+
<<~END
|
39
|
+
// OAuth2 requires session
|
40
|
+
session_start();
|
41
|
+
|
42
|
+
// Client instance
|
43
|
+
#{init}
|
44
|
+
// Check if we already have an access token
|
45
|
+
if (isset($_SESSION["access_token"])) {
|
46
|
+
// We're already authenticated, reuse the existing access token
|
47
|
+
$api->authenticate("oauth2", ["access_token" => $_SESSION["access_token"]]);
|
48
|
+
|
49
|
+
} else {
|
50
|
+
// Follow the OAuth2 authorization process to get an access token using
|
51
|
+
// authorization code
|
52
|
+
$api->authenticate("oauth2", [
|
53
|
+
// Client id and secret are given by the API server
|
54
|
+
"client_id" => "your client id",
|
55
|
+
"client_secret" => "your client secret",
|
56
|
+
|
57
|
+
// This example code should run on the URL below
|
58
|
+
"redirect_uri" => "https://your-client.tld/oauth2-callback",
|
59
|
+
|
60
|
+
// Scopes are specific to the API implementation
|
61
|
+
"scope" => "all",
|
62
|
+
]);
|
63
|
+
|
64
|
+
$provider = $api->getAuthenticationProvider();
|
65
|
+
|
66
|
+
// We don't have authorization code yet, request one
|
67
|
+
if (!isset($_GET['code'])) {
|
68
|
+
// Redirect the user to the authorization endpoint
|
69
|
+
$provider->requestAuthorizationCode();
|
70
|
+
exit;
|
71
|
+
|
72
|
+
} else {
|
73
|
+
// Request access token using the token endpoint
|
74
|
+
$provider->requestAccessToken();
|
75
|
+
|
76
|
+
// Store the access token in the session
|
77
|
+
$_SESSION['access_token'] = $provider->jsonSerialize();
|
78
|
+
}
|
79
|
+
}
|
80
|
+
END
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
@@ -96,7 +96,7 @@ END
|
|
96
96
|
|
97
97
|
return (out << response(sample)) if sample[:status]
|
98
98
|
|
99
|
-
out <<
|
99
|
+
out << '// Throws exception \\HaveAPI\\Client\\Exception\\ActionFailed'
|
100
100
|
out
|
101
101
|
end
|
102
102
|
|
@@ -107,7 +107,7 @@ END
|
|
107
107
|
when :hash
|
108
108
|
out << "// $reply is an instance of \\HaveAPI\\Client\\Response\n"
|
109
109
|
out << "// $reply->getResponse() returns an associative array of output parameters:\n"
|
110
|
-
out << format_parameters(:output, sample[:response] || {},
|
110
|
+
out << format_parameters(:output, sample[:response] || {}, '// ')
|
111
111
|
|
112
112
|
when :hash_list
|
113
113
|
out << "// $reply is an instance of \\HaveAPI\\Client\\Response\n"
|
@@ -116,31 +116,31 @@ END
|
|
116
116
|
when :object
|
117
117
|
out << "// $reply is an instance of \\HaveAPI\\Client\\ResourceInstance\n"
|
118
118
|
|
119
|
-
(sample[:response] || {}).each do |
|
120
|
-
param = action[:output][:parameters][
|
119
|
+
(sample[:response] || {}).each do |pn, pv|
|
120
|
+
param = action[:output][:parameters][pn]
|
121
121
|
|
122
122
|
if param[:type] == 'Resource'
|
123
|
-
out << "// $reply->#{
|
123
|
+
out << "// $reply->#{pn} = \\HaveAPI\\Client\\ResourceInstance("
|
124
124
|
out << "resource: #{param[:resource].join('.')}, "
|
125
125
|
|
126
|
-
if
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
126
|
+
out << if pv.is_a?(::Hash)
|
127
|
+
pv.map { |k, v| "#{k}: #{PP.pp(v, '').strip}" }.join(', ')
|
128
|
+
else
|
129
|
+
"id: #{pv}"
|
130
|
+
end
|
131
131
|
|
132
132
|
out << ")\n"
|
133
133
|
|
134
134
|
elsif param[:type] == 'Custom'
|
135
|
-
out << "// $reply->#{
|
135
|
+
out << "// $reply->#{pn} is a custom type"
|
136
136
|
|
137
137
|
else
|
138
|
-
out << "// $reply->#{
|
138
|
+
out << "// $reply->#{pn} = #{PP.pp(pv, '')}"
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
142
|
when :object_list
|
143
|
-
out <<
|
143
|
+
out << '// $reply is an instance of \\HaveAPI\\Client\\ResourceInstanceList'
|
144
144
|
end
|
145
145
|
|
146
146
|
out
|
@@ -150,12 +150,12 @@ END
|
|
150
150
|
ret = []
|
151
151
|
|
152
152
|
params.each do |k, v|
|
153
|
-
if action[dir][:parameters][k][:type] == 'Custom'
|
154
|
-
|
153
|
+
ret << if action[dir][:parameters][k][:type] == 'Custom'
|
154
|
+
"#{prefix} \"#{k}\" => custom type}"
|
155
155
|
|
156
|
-
|
157
|
-
|
158
|
-
|
156
|
+
else
|
157
|
+
"#{prefix} \"#{k}\" => #{value(v)}"
|
158
|
+
end
|
159
159
|
end
|
160
160
|
|
161
161
|
"#{prefix}[\n#{ret.join(",\n")}\n#{prefix}]"
|
@@ -163,6 +163,7 @@ END
|
|
163
163
|
|
164
164
|
def value(v)
|
165
165
|
return v if v.is_a?(::Numeric) || v === true || v === false
|
166
|
+
|
166
167
|
"\"#{v}\""
|
167
168
|
end
|
168
169
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module HaveAPI
|
2
|
-
module CLI
|
2
|
+
module CLI; end
|
3
3
|
end
|
4
4
|
|
5
5
|
require 'haveapi/cli/output_formatter'
|
@@ -18,28 +18,28 @@ module HaveAPI::ClientExamples
|
|
18
18
|
def auth(method, desc)
|
19
19
|
case method
|
20
20
|
when :basic
|
21
|
-
|
22
|
-
# Provide credentials on command line
|
23
|
-
#{init} --auth basic --user user --password secret
|
21
|
+
<<~END
|
22
|
+
# Provide credentials on command line
|
23
|
+
#{init} --auth basic --user user --password secret
|
24
24
|
|
25
|
-
# If username or password isn't provided, the user is asked on stdin
|
26
|
-
#{init} --auth basic --user user
|
27
|
-
Password: secret
|
28
|
-
END
|
25
|
+
# If username or password isn't provided, the user is asked on stdin
|
26
|
+
#{init} --auth basic --user user
|
27
|
+
Password: secret
|
28
|
+
END
|
29
29
|
|
30
30
|
when :token
|
31
|
-
|
32
|
-
# Get token using username and password and save it to disk
|
33
|
-
# Note that the client always has to call some action. APIs should provide
|
34
|
-
# an action to get information about the current user, so that's what we're
|
35
|
-
# calling now.
|
36
|
-
#{init} --auth token #{auth_token_credentials(desc, password: false).map { |k, v| "--#{k} #{v}" }.join(' ')} --save user current
|
37
|
-
Password: secret
|
38
|
-
|
39
|
-
# Now the token is read from disk and the user does not have to provide username
|
40
|
-
# nor password and be authenticated
|
41
|
-
#{init} user current
|
42
|
-
END
|
31
|
+
<<~END
|
32
|
+
# Get token using username and password and save it to disk
|
33
|
+
# Note that the client always has to call some action. APIs should provide
|
34
|
+
# an action to get information about the current user, so that's what we're
|
35
|
+
# calling now.
|
36
|
+
#{init} --auth token #{auth_token_credentials(desc, password: false).map { |k, v| "--#{k} #{v}" }.join(' ')} --save user current
|
37
|
+
Password: secret
|
38
|
+
|
39
|
+
# Now the token is read from disk and the user does not have to provide username
|
40
|
+
# nor password and be authenticated
|
41
|
+
#{init} user current
|
42
|
+
END
|
43
43
|
|
44
44
|
when :oauth2
|
45
45
|
'# OAuth2 is not supported by HaveAPI Ruby CLI.'
|
@@ -56,7 +56,7 @@ END
|
|
56
56
|
cmd << "-- \\\n"
|
57
57
|
|
58
58
|
res = cmd.join(' ') + sample[:request].map do |k, v|
|
59
|
-
' '*14 + input_param(k, v)
|
59
|
+
(' ' * 14) + input_param(k, v)
|
60
60
|
end.join(" \\\n")
|
61
61
|
|
62
62
|
else
|
@@ -84,32 +84,32 @@ END
|
|
84
84
|
|
85
85
|
action[:output][:parameters].each do |name, param|
|
86
86
|
col = {
|
87
|
-
name
|
88
|
-
align: %w
|
89
|
-
label: param[:label] && !param[:label].empty? ? param[:label] : name.upcase
|
87
|
+
name:,
|
88
|
+
align: %w[Integer Float].include?(param[:type]) ? 'right' : 'left',
|
89
|
+
label: param[:label] && !param[:label].empty? ? param[:label] : name.upcase
|
90
90
|
}
|
91
91
|
|
92
92
|
if param[:type] == 'Resource'
|
93
|
-
col[:display] =
|
93
|
+
col[:display] = proc do |r|
|
94
94
|
next '' unless r
|
95
95
|
next r unless r.is_a?(::Hash)
|
96
96
|
|
97
|
-
"#{r[
|
97
|
+
"#{r[param[:value_label].to_sym]} (##{r[param[:value_id].to_sym]})"
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
101
|
cols << col
|
102
102
|
end
|
103
103
|
|
104
|
-
res << "\n" << HaveAPI::CLI::OutputFormatter.
|
105
|
-
|
106
|
-
|
104
|
+
res << "\n" << HaveAPI::CLI::OutputFormatter.to_s(
|
105
|
+
sample[:response],
|
106
|
+
cols
|
107
107
|
)
|
108
108
|
res
|
109
109
|
end
|
110
110
|
|
111
111
|
def input_param(name, value)
|
112
|
-
option = name.to_s.gsub(
|
112
|
+
option = name.to_s.gsub('_', '-')
|
113
113
|
|
114
114
|
if action[:input][:parameters][name][:type] == 'Boolean'
|
115
115
|
return value ? "--#{option}" : "--no-#{name}"
|
@@ -8,34 +8,34 @@ module HaveAPI::ClientExamples
|
|
8
8
|
order 0
|
9
9
|
|
10
10
|
def init
|
11
|
-
|
12
|
-
require 'haveapi-client'
|
11
|
+
<<~END
|
12
|
+
require 'haveapi-client'
|
13
13
|
|
14
|
-
client = HaveAPI::Client.new("#{base_url}", version: "#{version}")
|
15
|
-
END
|
14
|
+
client = HaveAPI::Client.new("#{base_url}", version: "#{version}")
|
15
|
+
END
|
16
16
|
end
|
17
17
|
|
18
18
|
def auth(method, desc)
|
19
19
|
case method
|
20
20
|
when :basic
|
21
|
-
|
22
|
-
#{init}
|
21
|
+
<<~END
|
22
|
+
#{init}
|
23
23
|
|
24
|
-
client.authenticate(:basic, user: "user", password: "secret")
|
25
|
-
END
|
24
|
+
client.authenticate(:basic, user: "user", password: "secret")
|
25
|
+
END
|
26
26
|
|
27
27
|
when :token
|
28
|
-
|
29
|
-
#{init}
|
28
|
+
<<~END
|
29
|
+
#{init}
|
30
30
|
|
31
|
-
# Get token using username and password
|
32
|
-
client.authenticate(:token, #{auth_token_credentials(desc).map { |k, v| "#{k}: \"#{v}\"" }.join(', ')})
|
31
|
+
# Get token using username and password
|
32
|
+
client.authenticate(:token, #{auth_token_credentials(desc).map { |k, v| "#{k}: \"#{v}\"" }.join(', ')})
|
33
33
|
|
34
|
-
puts "Token = \#{client.auth.token}"
|
34
|
+
puts "Token = \#{client.auth.token}"
|
35
35
|
|
36
|
-
# Next time, the client can authenticate using the token directly
|
37
|
-
client.authenticate(:token, token: saved_token)
|
38
|
-
END
|
36
|
+
# Next time, the client can authenticate using the token directly
|
37
|
+
client.authenticate(:token, token: saved_token)
|
38
|
+
END
|
39
39
|
|
40
40
|
when :oauth2
|
41
41
|
'# OAuth2 is not supported by HaveAPI Ruby client.'
|
@@ -58,7 +58,7 @@ END
|
|
58
58
|
return (out << response(sample)) if sample[:status]
|
59
59
|
|
60
60
|
out << "\n"
|
61
|
-
out <<
|
61
|
+
out << '# Raises exception HaveAPI::Client::ActionFailed'
|
62
62
|
out
|
63
63
|
end
|
64
64
|
|
@@ -79,29 +79,29 @@ END
|
|
79
79
|
when :object
|
80
80
|
out << "# reply is an instance of HaveAPI::Client::ResourceInstance\n"
|
81
81
|
|
82
|
-
(sample[:response] || {}).each do |
|
82
|
+
(sample[:response] || {}).each do |pn, pv|
|
83
83
|
param = action[:output][:parameters][k]
|
84
84
|
|
85
85
|
if param[:type] == 'Resource'
|
86
|
-
out << "# reply.#{
|
86
|
+
out << "# reply.#{pn} = HaveAPI::Client::ResourceInstance("
|
87
87
|
out << "resource: #{param[:resource].join('.')}, "
|
88
88
|
|
89
|
-
if
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
89
|
+
out << if pv.is_a?(::Hash)
|
90
|
+
pv.map { |k, v| "#{k}: #{PP.pp(v, '').strip}" }.join(', ')
|
91
|
+
else
|
92
|
+
"id: #{pv}"
|
93
|
+
end
|
94
94
|
|
95
95
|
out << ")\n"
|
96
96
|
|
97
97
|
else
|
98
|
-
out << "# reply.#{
|
98
|
+
out << "# reply.#{pn} = #{PP.pp(pv, '')}"
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
102
|
when :object_list
|
103
103
|
out << "# reply is an instance of HaveAPI::Client::ResourceInstanceList,\n"
|
104
|
-
out <<
|
104
|
+
out << '# which is a subclass of Array'
|
105
105
|
end
|
106
106
|
|
107
107
|
out
|
data/lib/haveapi/common.rb
CHANGED
@@ -3,13 +3,13 @@ module HaveAPI
|
|
3
3
|
class << self
|
4
4
|
attr_accessor :custom_attrs
|
5
5
|
|
6
|
-
def has_attr(name, default=nil)
|
6
|
+
def has_attr(name, default = nil)
|
7
7
|
@custom_attrs ||= []
|
8
8
|
@custom_attrs << name
|
9
9
|
|
10
10
|
instance_variable_set("@#{name}", default)
|
11
11
|
|
12
|
-
self.class.send(:define_method, name) do |value=nil|
|
12
|
+
self.class.send(:define_method, name) do |value = nil|
|
13
13
|
if value.nil?
|
14
14
|
instance_variable_get("@#{name}")
|
15
15
|
else
|
@@ -34,8 +34,7 @@ module HaveAPI
|
|
34
34
|
|
35
35
|
def check_build(msg)
|
36
36
|
yield
|
37
|
-
|
38
|
-
rescue => e
|
37
|
+
rescue StandardError => e
|
39
38
|
raise BuildError.new(msg, e)
|
40
39
|
end
|
41
40
|
end
|
data/lib/haveapi/context.rb
CHANGED
@@ -5,8 +5,8 @@ module HaveAPI
|
|
5
5
|
:action_instance, :action_prepare, :layout
|
6
6
|
|
7
7
|
def initialize(server, version: nil, request: nil, resource: [], action: nil,
|
8
|
-
|
9
|
-
|
8
|
+
path: nil, args: nil, params: nil, user: nil,
|
9
|
+
authorization: nil, endpoint: nil, resource_path: [])
|
10
10
|
@server = server
|
11
11
|
@version = version
|
12
12
|
@request = request
|
@@ -33,7 +33,7 @@ module HaveAPI
|
|
33
33
|
ret
|
34
34
|
end
|
35
35
|
|
36
|
-
def path_for(action, args=nil)
|
36
|
+
def path_for(action, args = nil)
|
37
37
|
top_module = Kernel
|
38
38
|
top_route = @server.routes[@version]
|
39
39
|
|
@@ -42,16 +42,15 @@ module HaveAPI
|
|
42
42
|
|
43
43
|
begin
|
44
44
|
top_module.obj_type
|
45
|
-
|
46
45
|
rescue NoMethodError
|
47
46
|
next
|
48
47
|
end
|
49
48
|
|
50
|
-
if top_module.obj_type == :resource
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
49
|
+
top_route = if top_module.obj_type == :resource
|
50
|
+
top_route[:resources][top_module]
|
51
|
+
else
|
52
|
+
top_route[:actions][top_module]
|
53
|
+
end
|
55
54
|
end
|
56
55
|
|
57
56
|
ret = top_route.dup
|
@@ -65,6 +64,7 @@ module HaveAPI
|
|
65
64
|
ret = params && action.resolve_path_params(obj)
|
66
65
|
|
67
66
|
return [ret] if ret && !ret.is_a?(Array)
|
67
|
+
|
68
68
|
ret
|
69
69
|
end
|
70
70
|
|
@@ -87,10 +87,11 @@ module HaveAPI
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def action_scope
|
90
|
-
resource_path.map(&:downcase).join('.')
|
90
|
+
"#{resource_path.map(&:downcase).join('.')}##{action.action_name.underscore}"
|
91
91
|
end
|
92
92
|
|
93
93
|
private
|
94
|
+
|
94
95
|
def resolve_arg!(path, arg)
|
95
96
|
path.sub!(/\{[a-zA-Z\-_]+\}/, arg.to_s)
|
96
97
|
end
|
data/lib/haveapi/example.rb
CHANGED
@@ -50,9 +50,13 @@ module HaveAPI
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def provided?
|
53
|
-
instance_variables.detect do |v|
|
53
|
+
if instance_variables.detect do |v|
|
54
54
|
instance_variable_get(v)
|
55
|
-
end
|
55
|
+
end
|
56
|
+
true
|
57
|
+
else
|
58
|
+
false
|
59
|
+
end
|
56
60
|
end
|
57
61
|
|
58
62
|
def describe(context)
|
@@ -66,7 +70,7 @@ module HaveAPI
|
|
66
70
|
status: @status.nil? ? true : @status,
|
67
71
|
message: @message,
|
68
72
|
errors: @errors,
|
69
|
-
http_status: @http_status || 200
|
73
|
+
http_status: @http_status || 200
|
70
74
|
}
|
71
75
|
else
|
72
76
|
{}
|
@@ -74,12 +78,13 @@ module HaveAPI
|
|
74
78
|
end
|
75
79
|
|
76
80
|
protected
|
81
|
+
|
77
82
|
def filter_input_params(context, input)
|
78
83
|
case context.action.input.layout
|
79
84
|
when :object, :hash
|
80
85
|
context.authorization.filter_input(
|
81
86
|
context.action.input.params,
|
82
|
-
ModelAdapters::Hash.output(context, input)
|
87
|
+
ModelAdapters::Hash.output(context, input)
|
83
88
|
)
|
84
89
|
|
85
90
|
when :object_list, :hash_list
|
data/lib/haveapi/example_list.rb
CHANGED
data/lib/haveapi/exceptions.rb
CHANGED
@@ -4,7 +4,7 @@ module HaveAPI::Extensions
|
|
4
4
|
class ActionExceptions < Base
|
5
5
|
class << self
|
6
6
|
def enabled(server)
|
7
|
-
HaveAPI::Action.connect_hook(:exec_exception) do |ret,
|
7
|
+
HaveAPI::Action.connect_hook(:exec_exception) do |ret, _context, e|
|
8
8
|
break(ret) unless @exceptions
|
9
9
|
|
10
10
|
@exceptions.each do |handler|
|
@@ -20,7 +20,7 @@ module HaveAPI::Extensions
|
|
20
20
|
|
21
21
|
def rescue(klass, &block)
|
22
22
|
@exceptions ||= []
|
23
|
-
@exceptions << {
|
23
|
+
@exceptions << { klass:, block: }
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|