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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Rakefile +6 -6
  4. data/haveapi.gemspec +13 -13
  5. data/lib/haveapi/action.rb +153 -167
  6. data/lib/haveapi/action_state.rb +2 -6
  7. data/lib/haveapi/actions/default.rb +8 -10
  8. data/lib/haveapi/api.rb +2 -1
  9. data/lib/haveapi/authentication/base.rb +5 -8
  10. data/lib/haveapi/authentication/basic/provider.rb +4 -5
  11. data/lib/haveapi/authentication/chain.rb +19 -17
  12. data/lib/haveapi/authentication/oauth2/config.rb +12 -32
  13. data/lib/haveapi/authentication/oauth2/provider.rb +20 -30
  14. data/lib/haveapi/authentication/oauth2/revoke_endpoint.rb +1 -2
  15. data/lib/haveapi/authentication/token/action_config.rb +5 -3
  16. data/lib/haveapi/authentication/token/config.rb +5 -5
  17. data/lib/haveapi/authentication/token/provider.rb +33 -37
  18. data/lib/haveapi/authorization.rb +10 -4
  19. data/lib/haveapi/client_example.rb +11 -14
  20. data/lib/haveapi/client_examples/curl.rb +37 -37
  21. data/lib/haveapi/client_examples/fs_client.rb +29 -31
  22. data/lib/haveapi/client_examples/http.rb +35 -36
  23. data/lib/haveapi/client_examples/js_client.rb +62 -63
  24. data/lib/haveapi/client_examples/php_client.rb +77 -76
  25. data/lib/haveapi/client_examples/ruby_cli.rb +30 -30
  26. data/lib/haveapi/client_examples/ruby_client.rb +26 -26
  27. data/lib/haveapi/common.rb +3 -4
  28. data/lib/haveapi/context.rb +11 -10
  29. data/lib/haveapi/example.rb +9 -4
  30. data/lib/haveapi/example_list.rb +2 -2
  31. data/lib/haveapi/exceptions.rb +1 -1
  32. data/lib/haveapi/extensions/action_exceptions.rb +2 -2
  33. data/lib/haveapi/extensions/base.rb +1 -3
  34. data/lib/haveapi/extensions/exception_mailer.rb +260 -257
  35. data/lib/haveapi/hooks.rb +40 -39
  36. data/lib/haveapi/metadata.rb +1 -1
  37. data/lib/haveapi/model_adapter.rb +16 -27
  38. data/lib/haveapi/model_adapters/active_record.rb +59 -69
  39. data/lib/haveapi/output_formatter.rb +7 -7
  40. data/lib/haveapi/output_formatters/base.rb +2 -4
  41. data/lib/haveapi/parameters/resource.rb +7 -7
  42. data/lib/haveapi/parameters/typed.rb +6 -9
  43. data/lib/haveapi/params.rb +38 -45
  44. data/lib/haveapi/resource.rb +8 -8
  45. data/lib/haveapi/resources/action_state.rb +11 -19
  46. data/lib/haveapi/server.rb +102 -107
  47. data/lib/haveapi/spec/api_response.rb +1 -1
  48. data/lib/haveapi/spec/helpers.rb +1 -1
  49. data/lib/haveapi/spec/mock_action.rb +11 -10
  50. data/lib/haveapi/spec/spec_methods.rb +9 -8
  51. data/lib/haveapi/tasks/yard.rb +2 -2
  52. data/lib/haveapi/types.rb +0 -3
  53. data/lib/haveapi/validator.rb +6 -3
  54. data/lib/haveapi/validator_chain.rb +9 -8
  55. data/lib/haveapi/validators/acceptance.rb +6 -6
  56. data/lib/haveapi/validators/confirmation.rb +2 -3
  57. data/lib/haveapi/validators/exclusion.rb +1 -1
  58. data/lib/haveapi/validators/format.rb +1 -1
  59. data/lib/haveapi/validators/inclusion.rb +1 -1
  60. data/lib/haveapi/validators/length.rb +12 -11
  61. data/lib/haveapi/validators/numericality.rb +14 -13
  62. data/lib/haveapi/validators/presence.rb +4 -3
  63. data/lib/haveapi/version.rb +2 -2
  64. data/lib/haveapi.rb +2 -3
  65. data/spec/.rubocop.yml +4 -0
  66. data/spec/action/dsl_spec.rb +18 -18
  67. data/spec/authorization_spec.rb +8 -8
  68. data/spec/common_spec.rb +2 -1
  69. data/spec/documentation_spec.rb +2 -9
  70. data/spec/envelope_spec.rb +2 -2
  71. data/spec/hooks_spec.rb +12 -12
  72. data/spec/parameters/typed_spec.rb +6 -6
  73. data/spec/params_spec.rb +22 -24
  74. data/spec/resource_spec.rb +5 -7
  75. data/spec/spec_helper.rb +0 -1
  76. data/spec/validators/acceptance_spec.rb +1 -1
  77. data/spec/validators/confirmation_spec.rb +5 -5
  78. data/spec/validators/exclusion_spec.rb +3 -3
  79. data/spec/validators/format_spec.rb +2 -2
  80. data/spec/validators/inclusion_spec.rb +4 -4
  81. data/spec/validators/length_spec.rb +23 -23
  82. data/spec/validators/numericality_spec.rb +13 -13
  83. data/spec/validators/presence_spec.rb +3 -3
  84. metadata +49 -48
@@ -4,6 +4,11 @@ module HaveAPI
4
4
  @blocks = [block]
5
5
  end
6
6
 
7
+ def initialize_clone(other)
8
+ super
9
+ @blocks = other.instance_variable_get('@blocks').clone
10
+ end
11
+
7
12
  # Returns true if user is authorized.
8
13
  # Block must call allow to authorize user, default rule is deny.
9
14
  def authorized?(user, path_params)
@@ -33,8 +38,8 @@ module HaveAPI
33
38
  # @param blacklist [Array<Symbol>] allow all parameters except listed ones
34
39
  def input(whitelist: nil, blacklist: nil)
35
40
  @input = {
36
- whitelist: whitelist,
37
- blacklist: blacklist,
41
+ whitelist:,
42
+ blacklist:
38
43
  }
39
44
  end
40
45
 
@@ -43,8 +48,8 @@ module HaveAPI
43
48
  # @param blacklist [Array<Symbol>] allow all parameters except listed ones
44
49
  def output(whitelist: nil, blacklist: nil)
45
50
  @output = {
46
- whitelist: whitelist,
47
- blacklist: blacklist,
51
+ whitelist:,
52
+ blacklist:
48
53
  }
49
54
  end
50
55
 
@@ -75,6 +80,7 @@ module HaveAPI
75
80
  end
76
81
 
77
82
  private
83
+
78
84
  def filter_inner(allowed_params, direction, params, format)
79
85
  allowed = {}
80
86
 
@@ -1,5 +1,5 @@
1
1
  module HaveAPI
2
- module ClientExamples ; end
2
+ module ClientExamples; end
3
3
 
4
4
  # All client example classes should inherit this class. Depending on the client,
5
5
  # the subclass may choose to implement either method `example` or `request` and
@@ -39,13 +39,13 @@ module HaveAPI
39
39
  end
40
40
 
41
41
  # Shortcut to {ClientExample#init}
42
- def init(*args)
43
- new(*args).init
42
+ def init(*)
43
+ new(*).init
44
44
  end
45
45
 
46
46
  # Shortcut to {ClientExample#auth}
47
47
  def auth(*args)
48
- new(*args[0..-3]).auth(*args[-2..-1])
48
+ new(*args[0..-3]).auth(*args[-2..])
49
49
  end
50
50
 
51
51
  # Shortcut to {ClientExample#example}
@@ -68,30 +68,27 @@ module HaveAPI
68
68
  @resource_path, @resource, @action_name, @action = args
69
69
  end
70
70
 
71
- def init
71
+ def init; end
72
72
 
73
- end
74
-
75
- def auth(method, desc)
76
-
77
- end
73
+ def auth(method, desc); end
78
74
 
79
75
  def version_url
80
76
  File.join(base_url, "v#{version}", '/')
81
77
  end
82
78
 
83
79
  protected
80
+
84
81
  # @param password [Boolean] include password parameter
85
82
  # @return [Hash<String, String>] parameter => example value
86
83
  def auth_token_credentials(desc, password: true)
87
- passwords = %i(password pass passwd)
88
- params = desc[:resources][:token][:actions]['request'][:input][:parameters].keys - %i(lifetime interval)
84
+ passwords = %i[password pass passwd]
85
+ params = desc[:resources][:token][:actions]['request'][:input][:parameters].keys - %i[lifetime interval]
89
86
 
90
87
  unless password
91
88
  params.reject! { |param| passwords.include?(param) }
92
89
  end
93
90
 
94
- Hash[params.map do |param|
91
+ params.to_h do |param|
95
92
  value =
96
93
  if passwords.include?(param)
97
94
  'secret'
@@ -100,7 +97,7 @@ module HaveAPI
100
97
  end
101
98
 
102
99
  [param, value]
103
- end]
100
+ end
104
101
  end
105
102
  end
106
103
  end
@@ -14,34 +14,34 @@ module HaveAPI::ClientExamples
14
14
  def auth(method, desc)
15
15
  case method
16
16
  when :basic
17
- <<END
18
- # Password is asked on standard input
19
- $ curl --request OPTIONS \\
20
- --user username \\
21
- '#{base_url}'
22
- Password: secret
17
+ <<~END
18
+ # Password is asked on standard input
19
+ $ curl --request OPTIONS \\
20
+ --user username \\
21
+ '#{base_url}'
22
+ Password: secret
23
23
 
24
- # Password given on the command line
25
- $ curl --request OPTIONS \\
26
- --user username:secret \\
27
- '#{base_url}'
28
- END
24
+ # Password given on the command line
25
+ $ curl --request OPTIONS \\
26
+ --user username:secret \\
27
+ '#{base_url}'
28
+ END
29
29
 
30
30
  when :token
31
31
  login = auth_token_credentials(desc).merge(lifetime: 'fixed')
32
32
 
33
- <<END
34
- # Acquire the token
35
- $ curl --request POST \\
36
- --header 'Content-Type: application/json' \\
37
- --data-binary "#{format_data(token: login)}" \\
38
- '#{File.join(base_url, '_auth', 'token', 'tokens')}'
33
+ <<~END
34
+ # Acquire the token
35
+ $ curl --request POST \\
36
+ --header 'Content-Type: application/json' \\
37
+ --data-binary "#{format_data(token: login)}" \\
38
+ '#{File.join(base_url, '_auth', 'token', 'tokens')}'
39
39
 
40
- # Use a previously acquired token
41
- $ curl --request OPTIONS \\
42
- --header '#{desc[:http_header]}: thetoken' \\
43
- '#{base_url}'
44
- END
40
+ # Use a previously acquired token
41
+ $ curl --request OPTIONS \\
42
+ --header '#{desc[:http_header]}: thetoken' \\
43
+ '#{base_url}'
44
+ END
45
45
 
46
46
  when :oauth2
47
47
  '# See RFC 6749 for authorization process and RFC 6750 for access token usage.'
@@ -50,32 +50,32 @@ END
50
50
 
51
51
  def request(sample)
52
52
  url = File.join(
53
- base_url,
54
- resolve_path(
55
- action[:method],
56
- action[:path],
57
- sample[:path_params] || [],
58
- sample[:request]
59
- )
53
+ base_url,
54
+ resolve_path(
55
+ action[:method],
56
+ action[:path],
57
+ sample[:path_params] || [],
58
+ sample[:request]
59
+ )
60
60
  )
61
61
 
62
62
  data = format_data({
63
- action[:input][:namespace] => sample[:request],
63
+ action[:input][:namespace] => sample[:request]
64
64
  })
65
65
 
66
- <<END
67
- $ curl --request #{action[:method]} \\
68
- --data-binary "#{data}" \\
69
- '#{url}'
70
- END
66
+ <<~END
67
+ $ curl --request #{action[:method]} \\
68
+ --data-binary "#{data}" \\
69
+ '#{url}'
70
+ END
71
71
  end
72
72
 
73
73
  def response(sample)
74
74
  JSON.pretty_generate({
75
75
  status: sample[:status],
76
76
  message: sample[:message],
77
- response: {action[:output][:namespace] => sample[:response]},
78
- errors: sample[:errors],
77
+ response: { action[:output][:namespace] => sample[:response] },
78
+ errors: sample[:errors]
79
79
  })
80
80
  end
81
81
 
@@ -13,27 +13,27 @@ module HaveAPI::ClientExamples
13
13
  def auth(method, desc)
14
14
  case method
15
15
  when :basic
16
- <<END
17
- # Provide credentials as file system options
18
- #{init} -o auth_method=basic,user=myuser,password=secret
16
+ <<~END
17
+ # Provide credentials as file system options
18
+ #{init} -o auth_method=basic,user=myuser,password=secret
19
19
 
20
- # If username or password isn't provided, the user is asked on stdin
21
- #{init} -o auth_method=basic,user=myuser
22
- Password: secret
23
- END
20
+ # If username or password isn't provided, the user is asked on stdin
21
+ #{init} -o auth_method=basic,user=myuser
22
+ Password: secret
23
+ END
24
24
 
25
25
  when :token
26
- <<END
27
- # Authenticate using username and password
28
- #{init} -o auth_method=token,user=myuser
29
- Password: secret
26
+ <<~END
27
+ # Authenticate using username and password
28
+ #{init} -o auth_method=token,user=myuser
29
+ Password: secret
30
30
 
31
- # If you have generated a token, you can use it
32
- #{init} -o auth_method=token,token=yourtoken
31
+ # If you have generated a token, you can use it
32
+ #{init} -o auth_method=token,token=yourtoken
33
33
 
34
- # Note that the file system can read config file from haveapi-client, so if
35
- # you set up authentication there, the file system will use it.
36
- END
34
+ # Note that the file system can read config file from haveapi-client, so if
35
+ # you set up authentication there, the file system will use it.
36
+ END
37
37
 
38
38
  when :oauth2
39
39
  '# OAuth2 is not supported by haveapi-fs.'
@@ -47,9 +47,7 @@ END
47
47
 
48
48
  unless class_action?
49
49
  if !sample[:path_params] || sample[:path_params].empty?
50
- fail "example {#{sample}} of action #{resource_path.join('.')}"+
51
- ".#{action_name} is for an instance action but does not include "+
52
- "URL parameters"
50
+ raise "example {#{sample}} of action #{resource_path.join('.')}.#{action_name} is for an instance action but does not include URL parameters"
53
51
  end
54
52
 
55
53
  path << sample[:path_params].first.to_s
@@ -69,29 +67,29 @@ END
69
67
  end
70
68
 
71
69
  cmd << "\n# Execute the action"
72
- cmd << "$ echo 1 > exec"
70
+ cmd << '$ echo 1 > exec'
73
71
 
74
72
  cmd << "\n# Query the action's result"
75
- cmd << "$ cat status"
73
+ cmd << '$ cat status'
76
74
  cmd << (sample[:status] ? '1' : '0')
77
75
 
78
76
  if sample[:status]
79
77
  if sample[:response] && !sample[:response].empty? \
80
- && %i(hash object).include?(action[:output][:layout])
78
+ && %i[hash object].include?(action[:output][:layout])
81
79
  cmd << "\n# Query the output parameters"
82
80
 
83
81
  sample[:response].each do |k, v|
84
82
  cmd << "$ cat output/#{k}"
85
83
 
86
- if v === true
87
- cmd << '1'
84
+ cmd << if v === true
85
+ '1'
88
86
 
89
- elsif v === false
90
- cmd << '0'
87
+ elsif v === false
88
+ '0'
91
89
 
92
- else
93
- cmd << "#{v.to_s}"
94
- end
90
+ else
91
+ v.to_s
92
+ end
95
93
 
96
94
  cmd << "\n"
97
95
  end
@@ -99,11 +97,11 @@ END
99
97
 
100
98
  else
101
99
  cmd << "\n# Get the error message"
102
- cmd << "$ cat message"
100
+ cmd << '$ cat message'
103
101
  cmd << sample[:message]
104
102
 
105
103
  cmd << "\n# Parameter errors can be seen in the `errors` directory"
106
- cmd << "$ ls errors"
104
+ cmd << '$ ls errors'
107
105
  cmd << (sample[:errors] || {}).keys.join("\n")
108
106
  end
109
107
 
@@ -1,4 +1,3 @@
1
- require 'pp'
2
1
  require 'cgi'
3
2
  require 'rack/utils'
4
3
  require 'haveapi/client_example'
@@ -10,61 +9,61 @@ module HaveAPI::ClientExamples
10
9
  order 100
11
10
 
12
11
  def init
13
- <<END
14
- OPTIONS /v#{version}/ HTTP/1.1
15
- Host: #{host}
12
+ <<~END
13
+ OPTIONS /v#{version}/ HTTP/1.1
14
+ Host: #{host}
16
15
 
17
- END
16
+ END
18
17
  end
19
18
 
20
19
  def auth(method, desc)
21
20
  case method
22
21
  when :basic
23
- <<END
24
- GET / HTTP/1.1
25
- Host: #{host}
26
- Authorization: Basic dXNlcjpzZWNyZXQ=
22
+ <<~END
23
+ GET / HTTP/1.1
24
+ Host: #{host}
25
+ Authorization: Basic dXNlcjpzZWNyZXQ=
27
26
 
28
- END
27
+ END
29
28
 
30
29
  when :token
31
30
  login = auth_token_credentials(desc).merge(lifetime: 'fixed')
32
31
 
33
- <<END
34
- POST /_auth/token/tokens HTTP/1.1
35
- Host: #{host}
36
- Content-Type: application/json
32
+ <<~END
33
+ POST /_auth/token/tokens HTTP/1.1
34
+ Host: #{host}
35
+ Content-Type: application/json
37
36
 
38
- #{JSON.pretty_generate({token: login})}
39
- END
37
+ #{JSON.pretty_generate({ token: login })}
38
+ END
40
39
 
41
40
  when :oauth2
42
- <<END
43
- # 1) Request authorization code
44
- GET #{desc[:authorize_path]}?response_type=code&client_id=$client_id&state=$state&redirect_uri=$client_redirect_uri HTTP/1.1
45
- Host: #{host}
41
+ <<~END
42
+ # 1) Request authorization code
43
+ GET #{desc[:authorize_path]}?response_type=code&client_id=$client_id&state=$state&redirect_uri=$client_redirect_uri HTTP/1.1
44
+ Host: #{host}
46
45
 
47
- # 2) The user logs in using this API
46
+ # 2) The user logs in using this API
48
47
 
49
- # 3) The API then redirects the user back to the client application
50
- GET $client_redirect_uri?code=$authorization_code&state=$state
51
- Host: client-application
48
+ # 3) The API then redirects the user back to the client application
49
+ GET $client_redirect_uri?code=$authorization_code&state=$state
50
+ Host: client-application
52
51
 
53
- # 4) The client application requests access token
54
- POST #{desc[:token_path]}
55
- Content-Type: application/x-www-form-urlencoded
52
+ # 4) The client application requests access token
53
+ POST #{desc[:token_path]}
54
+ Content-Type: application/x-www-form-urlencoded
56
55
 
57
- grant_type=authorization_code&code=$authorization_code&redirect_uri=$client_redirect_uri&client_id=$client_id&client_secret=$client_secret
58
- END
56
+ grant_type=authorization_code&code=$authorization_code&redirect_uri=$client_redirect_uri&client_id=$client_id&client_secret=$client_secret
57
+ END
59
58
  end
60
59
  end
61
60
 
62
61
  def request(sample)
63
62
  path = resolve_path(
64
- action[:method],
65
- action[:path],
66
- sample[:path_params] || [],
67
- sample[:request]
63
+ action[:method],
64
+ action[:path],
65
+ sample[:path_params] || [],
66
+ sample[:request]
68
67
  )
69
68
 
70
69
  req = "#{action[:method]} #{path} HTTP/1.1\n"
@@ -72,7 +71,7 @@ END
72
71
  req << "Content-Type: application/json\n\n"
73
72
 
74
73
  if action[:method] != 'GET' && sample[:request] && !sample[:request].empty?
75
- req << JSON.pretty_generate({action[:input][:namespace] => sample[:request]})
74
+ req << JSON.pretty_generate({ action[:input][:namespace] => sample[:request] })
76
75
  end
77
76
 
78
77
  req
@@ -82,8 +81,8 @@ END
82
81
  content = JSON.pretty_generate({
83
82
  status: sample[:status],
84
83
  message: sample[:message],
85
- response: {action[:output][:namespace] => sample[:response]},
86
- errors: sample[:errors],
84
+ response: { action[:output][:namespace] => sample[:response] },
85
+ errors: sample[:errors]
87
86
  })
88
87
 
89
88
  status_msg = Rack::Utils::HTTP_STATUS_CODES[sample[:http_status]]
@@ -7,61 +7,61 @@ module HaveAPI::ClientExamples
7
7
  order 10
8
8
 
9
9
  def init
10
- <<END
11
- import HaveAPI from 'haveapi-client'
10
+ <<~END
11
+ import HaveAPI from 'haveapi-client'
12
12
 
13
- var api = new HaveAPI.Client("#{base_url}", {version: "#{version}"});
14
- END
13
+ var api = new HaveAPI.Client("#{base_url}", {version: "#{version}"});
14
+ END
15
15
  end
16
16
 
17
17
  def auth(method, desc)
18
18
  case method
19
19
  when :basic
20
- <<END
21
- #{init}
20
+ <<~END
21
+ #{init}
22
22
 
23
- api.authenticate("basic", {
24
- user: "user",
25
- password: "secret"
26
- }, function (client, status) {
27
- console.log("Authenticated?", status);
28
- });
29
- END
23
+ api.authenticate("basic", {
24
+ user: "user",
25
+ password: "secret"
26
+ }, function (client, status) {
27
+ console.log("Authenticated?", status);
28
+ });
29
+ END
30
30
 
31
31
  when :token
32
- <<END
33
- #{init}
34
-
35
- // Request a new token
36
- api.authenticate("token", {
37
- #{auth_token_credentials(desc).map { |k, v| "#{k}: \"#{v}\"" }.join(",\n ")}
38
- }, function (client, status) {
39
- console.log("Authenticated?", status);
40
-
41
- if (status)
42
- console.log("Token is", client.authProvider.token);
43
- });
44
-
45
- // Use an existing token
46
- api.authenticate("token", {
47
- token: "qwertyuiop..."
48
- }, function (client, status) {
49
- console.log("Authenticated?", status);
50
- });
51
- END
32
+ <<~END
33
+ #{init}
34
+
35
+ // Request a new token
36
+ api.authenticate("token", {
37
+ #{auth_token_credentials(desc).map { |k, v| "#{k}: \"#{v}\"" }.join(",\n ")}
38
+ }, function (client, status) {
39
+ console.log("Authenticated?", status);
40
+
41
+ if (status)
42
+ console.log("Token is", client.authProvider.token);
43
+ });
44
+
45
+ // Use an existing token
46
+ api.authenticate("token", {
47
+ token: "qwertyuiop..."
48
+ }, function (client, status) {
49
+ console.log("Authenticated?", status);
50
+ });
51
+ END
52
52
 
53
53
  when :oauth2
54
- <<END
55
- #{init}
56
- // The JavaScript client must be configured with OAuth2 access token, it does not
57
- // support the authorization procedure to obtain a new access token.
58
- var accessToken = {
59
- access_token: "the access token"
60
- };
61
-
62
- // The client is authenticated immediately, no need for a callback
63
- api.authenticate("oauth2", {access_token: accessToken});
64
- END
54
+ <<~END
55
+ #{init}
56
+ // The JavaScript client must be configured with OAuth2 access token, it does not
57
+ // support the authorization procedure to obtain a new access token.
58
+ var accessToken = {
59
+ access_token: "the access token"
60
+ };
61
+
62
+ // The client is authenticated immediately, no need for a callback
63
+ api.authenticate("oauth2", {access_token: accessToken});
64
+ END
65
65
  end
66
66
  end
67
67
 
@@ -82,14 +82,14 @@ END
82
82
  callback = "function (client, reply) {\n"
83
83
  callback << " console.log('Response', reply);\n"
84
84
 
85
- if sample[:status]
86
- callback << response(sample)
85
+ callback << if sample[:status]
86
+ response(sample)
87
87
 
88
- else
89
- callback << error(sample)
90
- end
88
+ else
89
+ error(sample)
90
+ end
91
91
 
92
- callback << "}"
92
+ callback << '}'
93
93
 
94
94
  out << callback.strip
95
95
  out << ');'
@@ -117,30 +117,30 @@ END
117
117
  when :object
118
118
  out << " // reply is an instance of HaveAPI.Client.ResourceInstance\n"
119
119
 
120
- (sample[:response] || {}).each do |k, v|
121
- param = action[:output][:parameters][k]
120
+ (sample[:response] || {}).each do |pn, pv|
121
+ param = action[:output][:parameters][pn]
122
122
 
123
123
  if param[:type] == 'Resource'
124
- out << " // reply.#{k} = HaveAPI.Client.ResourceInstance("
124
+ out << " // reply.#{pn} = HaveAPI.Client.ResourceInstance("
125
125
  out << "resource: #{param[:resource].join('.')}, "
126
126
 
127
- if v.is_a?(::Hash)
128
- out << v.map { |k,v| "#{k}: #{PP.pp(v, '').strip}" }.join(', ')
129
- else
130
- out << "id: #{v}"
131
- end
127
+ out << if pv.is_a?(::Hash)
128
+ pv.map { |k, v| "#{k}: #{PP.pp(v, '').strip}" }.join(', ')
129
+ else
130
+ "id: #{pv}"
131
+ end
132
132
 
133
133
  out << ")\n"
134
134
 
135
- elsif param[:type] == 'Custom' && (v.is_a?(::Hash) || v.is_a?(::Array))
136
- json = JSON.pretty_generate(v).split("\n").map do |v|
135
+ elsif param[:type] == 'Custom' && (pv.is_a?(::Hash) || pv.is_a?(::Array))
136
+ json = JSON.pretty_generate(pv).split("\n").map do |v|
137
137
  " // #{v}"
138
138
  end.join("\n")
139
139
 
140
- out << " // reply.#{k} = #{json}"
140
+ out << " // reply.#{pn} = #{json}"
141
141
 
142
142
  else
143
- out << " // reply.#{k} = #{PP.pp(v, '')}"
143
+ out << " // reply.#{pn} = #{PP.pp(pv, '')}"
144
144
  end
145
145
  end
146
146
 
@@ -149,7 +149,6 @@ END
149
149
  end
150
150
 
151
151
  out
152
-
153
152
  end
154
153
 
155
154
  def error(sample)