haveapi 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 +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
|