grape 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grape might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d283d4483281266120c9894d4abf116577e4f6d0
4
- data.tar.gz: d730405b71975b6d471a9fd0366bc49715377725
3
+ metadata.gz: f90062d2ff701a0d5a85be85c6658ba4f586849b
4
+ data.tar.gz: f43b46740851eb22a55e1fae15c8173875d5da9f
5
5
  SHA512:
6
- metadata.gz: 134c53c62b330e7ff63acb341d30ae493b303d29610d57a8746796533698e9c83addbee84836440a921240f3a38451139e3699ec3f273cfb2eaeabdb162c1560
7
- data.tar.gz: dd02f3635d42061cdfe7ee32984541c0284f39c38c38b3e541b409ba64af66cfd9f691c400c68ff899d42e387784a25e08eb8176e462c04995b3f8b55363d180
6
+ metadata.gz: c3385b8c8c88db4eefd090030a8b73af0cd00b7b5ff5a247221a21fddfb3956d0268a7b2ed40ef74e222dee81fc4c5b3e99065501d5b044297e50edfc3c32054
7
+ data.tar.gz: 7cd058957cf3f3d8e770db3887a016e9a0dfa000985487973afb399203a1fda0a0a95a94e2e4a3541a2641008197d94c182ef4d92a85ffde0def8440099184bc
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ### 1.0.1 (9/8/2017)
2
+
3
+ #### Features
4
+
5
+ * [#1652](https://github.com/ruby-grape/grape/pull/1652): Add the original exception to the error_formatter the original exception - [@dcsg](https://github.com/dcsg).
6
+ * [#1665](https://github.com/ruby-grape/grape/pull/1665): Make helpers available in subclasses - [@pablonahuelgomez](https://github.com/pablonahuelgomez).
7
+ * [#1674](https://github.com/ruby-grape/grape/pull/1674): Add parameter alias (`as`) - [@glaucocustodio](https://github.com/glaucocustodio).
8
+
9
+ #### Fixes
10
+
11
+ * [#1652](https://github.com/ruby-grape/grape/pull/1652): Fix missing backtrace that was not being bubbled up to the `error_formatter` - [@dcsg](https://github.com/dcsg).
12
+ * [#1661](https://github.com/ruby-grape/grape/pull/1661): Handle deeply-nested dependencies correctly - [@rnubel](https://github.com/rnubel), [@jnardone](https://github.com/jnardone).
13
+ * [#1679](https://github.com/ruby-grape/grape/pull/1679): Treat StandardError from explicit values validator proc as false - [@jlfaber](https://github.com/jlfaber).
14
+
1
15
  ### 1.0.0 (7/3/2017)
2
16
 
3
17
  #### Features
data/Gemfile CHANGED
@@ -24,7 +24,7 @@ end
24
24
  group :test do
25
25
  gem 'grape-entity', '~> 0.6'
26
26
  gem 'maruku'
27
- gem 'rack-test'
27
+ gem 'rack-test', '~> 0.6.3'
28
28
  gem 'rspec', '~> 3.0'
29
29
  gem 'cookiejar'
30
30
  gem 'rack-jsonp', require: 'rack/jsonp'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grape (1.0.0)
4
+ grape (1.0.1)
5
5
  activesupport
6
6
  builder
7
7
  mustermann-grape (~> 1.0.0)
@@ -12,13 +12,13 @@ PATH
12
12
  GEM
13
13
  remote: https://rubygems.org/
14
14
  specs:
15
- activesupport (5.1.2)
15
+ activesupport (5.1.4)
16
16
  concurrent-ruby (~> 1.0, >= 1.0.2)
17
17
  i18n (~> 0.7)
18
18
  minitest (~> 5.1)
19
19
  tzinfo (~> 1.1)
20
- addressable (2.5.1)
21
- public_suffix (~> 2.0, >= 2.0.2)
20
+ addressable (2.5.2)
21
+ public_suffix (>= 2.0.2, < 4.0)
22
22
  appraisal (2.2.0)
23
23
  bundler
24
24
  rake
@@ -35,7 +35,7 @@ GEM
35
35
  cork
36
36
  nap
37
37
  open4 (~> 1.3)
38
- coderay (1.1.1)
38
+ coderay (1.1.2)
39
39
  coercible (1.0.0)
40
40
  descendants_tracker (~> 0.0.1)
41
41
  colored (1.2)
@@ -70,7 +70,7 @@ GEM
70
70
  diff-lcs (1.3)
71
71
  docile (1.1.5)
72
72
  equalizer (0.0.11)
73
- faraday (0.12.1)
73
+ faraday (0.13.1)
74
74
  multipart-post (>= 1.2, < 3)
75
75
  faraday-http-cache (1.3.1)
76
76
  faraday (~> 0.8)
@@ -97,8 +97,8 @@ GEM
97
97
  guard-rubocop (1.3.0)
98
98
  guard (~> 2.0)
99
99
  rubocop (~> 0.20)
100
- hashie (3.5.5)
101
- i18n (0.8.4)
100
+ hashie (3.5.6)
101
+ i18n (0.8.6)
102
102
  ice_nine (0.11.2)
103
103
  json (2.1.0)
104
104
  kramdown (1.14.0)
@@ -112,10 +112,10 @@ GEM
112
112
  mime-types (3.1)
113
113
  mime-types-data (~> 3.2015)
114
114
  mime-types-data (3.2016.0521)
115
- minitest (5.10.2)
116
- multi_json (1.12.1)
115
+ minitest (5.10.3)
116
+ multi_json (1.12.2)
117
117
  multipart-post (2.0.0)
118
- mustermann (1.0.0)
118
+ mustermann (1.0.1)
119
119
  mustermann-grape (1.0.0)
120
120
  mustermann (~> 1.0.0)
121
121
  nap (1.1.0)
@@ -133,7 +133,7 @@ GEM
133
133
  coderay (~> 1.1.0)
134
134
  method_source (~> 0.8.1)
135
135
  slop (~> 3.4)
136
- public_suffix (2.0.5)
136
+ public_suffix (3.0.0)
137
137
  rack (2.0.3)
138
138
  rack-accept (0.4.5)
139
139
  rack (>= 0.4)
@@ -180,7 +180,7 @@ GEM
180
180
  docile (~> 1.1.0)
181
181
  json (>= 1.8, < 3)
182
182
  simplecov-html (~> 0.10.0)
183
- simplecov-html (0.10.1)
183
+ simplecov-html (0.10.2)
184
184
  slop (3.6.0)
185
185
  term-ansicolor (1.6.0)
186
186
  tins (~> 1.0)
@@ -217,7 +217,7 @@ DEPENDENCIES
217
217
  maruku
218
218
  mime-types
219
219
  rack-jsonp
220
- rack-test
220
+ rack-test (~> 0.6.3)
221
221
  rake
222
222
  redcarpet
223
223
  rspec (~> 3.0)
@@ -226,4 +226,4 @@ DEPENDENCIES
226
226
  yard
227
227
 
228
228
  BUNDLED WITH
229
- 1.14.6
229
+ 1.15.3
data/README.md CHANGED
@@ -42,6 +42,7 @@
42
42
  - [Validation of Nested Parameters](#validation-of-nested-parameters)
43
43
  - [Dependent Parameters](#dependent-parameters)
44
44
  - [Group Options](#group-options)
45
+ - [Alias](#alias)
45
46
  - [Built-in Validators](#built-in-validators)
46
47
  - [Namespace Validation and Coercion](#namespace-validation-and-coercion)
47
48
  - [Custom Validators](#custom-validators)
@@ -109,7 +110,7 @@ content negotiation, versioning and much more.
109
110
 
110
111
  ## Stable Release
111
112
 
112
- You're reading the documentation for the stable release of Grape, 1.0.0.
113
+ You're reading the documentation for the stable release of Grape, 1.0.1.
113
114
  Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
114
115
 
115
116
  ## Project Resources
@@ -1093,6 +1094,23 @@ params do
1093
1094
  end
1094
1095
  ```
1095
1096
 
1097
+ ### Alias
1098
+
1099
+ You can set an alias for parameters using `as`, which can be useful when refactoring existing APIs:
1100
+
1101
+ ```ruby
1102
+ resource :users do
1103
+ params do
1104
+ requires :email_address, as: :email
1105
+ requires :password
1106
+ end
1107
+ post do
1108
+ User.create!(declared(params)) # User takes email and password
1109
+ end
1110
+ end
1111
+ ```
1112
+
1113
+ The value passed to `as` will be the key when calling `params` or `declared(params)`.
1096
1114
 
1097
1115
  ### Built-in Validators
1098
1116
 
@@ -1160,7 +1178,8 @@ end
1160
1178
 
1161
1179
  Alternatively, a Proc with arity one (i.e. taking one argument) can be used to explicitly validate
1162
1180
  each parameter value. In that case, the Proc is expected to return a truthy value if the parameter
1163
- value is valid.
1181
+ value is valid. The parameter will be considered invalid if the Proc returns a falsy value or if it
1182
+ raises a StandardError.
1164
1183
 
1165
1184
  ```ruby
1166
1185
  params do
@@ -24,7 +24,7 @@ end
24
24
  group :test do
25
25
  gem 'grape-entity', '~> 0.6'
26
26
  gem 'maruku'
27
- gem 'rack-test'
27
+ gem 'rack-test', '~> 0.6.3'
28
28
  gem 'rspec', '~> 3.0'
29
29
  gem 'cookiejar'
30
30
  gem 'rack-jsonp', require: 'rack/jsonp'
@@ -24,7 +24,7 @@ end
24
24
  group :test do
25
25
  gem 'grape-entity', '~> 0.6'
26
26
  gem 'maruku'
27
- gem 'rack-test'
27
+ gem 'rack-test', '~> 0.6.3'
28
28
  gem 'rspec', '~> 3.0'
29
29
  gem 'cookiejar'
30
30
  gem 'rack-jsonp', require: 'rack/jsonp'
@@ -24,7 +24,7 @@ end
24
24
  group :test do
25
25
  gem 'grape-entity', '~> 0.6'
26
26
  gem 'maruku'
27
- gem 'rack-test'
27
+ gem 'rack-test', '~> 0.6.3'
28
28
  gem 'rspec', '~> 3.0'
29
29
  gem 'cookiejar'
30
30
  gem 'rack-jsonp', require: 'rack/jsonp'
@@ -24,7 +24,7 @@ end
24
24
  group :test do
25
25
  gem 'grape-entity', '~> 0.6'
26
26
  gem 'maruku'
27
- gem 'rack-test'
27
+ gem 'rack-test', '~> 0.6.3'
28
28
  gem 'rspec', '~> 3.0'
29
29
  gem 'cookiejar'
30
30
  gem 'rack-jsonp', require: 'rack/jsonp'
@@ -25,7 +25,7 @@ end
25
25
  group :test do
26
26
  gem 'grape-entity', '~> 0.6'
27
27
  gem 'maruku'
28
- gem 'rack-test'
28
+ gem 'rack-test', '~> 0.6.3'
29
29
  gem 'rspec', '~> 3.0'
30
30
  gem 'cookiejar'
31
31
  gem 'rack-jsonp', require: 'rack/jsonp'
@@ -24,7 +24,7 @@ end
24
24
  group :test do
25
25
  gem 'grape-entity', '~> 0.6'
26
26
  gem 'maruku'
27
- gem 'rack-test'
27
+ gem 'rack-test', '~> 0.6.3'
28
28
  gem 'rspec', '~> 3.0'
29
29
  gem 'cookiejar'
30
30
  gem 'rack-jsonp', require: 'rack/jsonp'
@@ -24,7 +24,7 @@ end
24
24
  group :test do
25
25
  gem 'grape-entity', '~> 0.6'
26
26
  gem 'maruku'
27
- gem 'rack-test'
27
+ gem 'rack-test', '~> 0.6.3'
28
28
  gem 'rspec', '~> 3.0'
29
29
  gem 'cookiejar'
30
30
  gem 'rack-jsonp', require: 'rack/jsonp'
@@ -24,7 +24,7 @@ end
24
24
  group :test do
25
25
  gem 'grape-entity', '~> 0.6'
26
26
  gem 'maruku'
27
- gem 'rack-test'
27
+ gem 'rack-test', '~> 0.6.3'
28
28
  gem 'rspec', '~> 3.0'
29
29
  gem 'cookiejar'
30
30
  gem 'rack-jsonp', require: 'rack/jsonp'
data/lib/grape.rb CHANGED
@@ -13,6 +13,7 @@ require 'active_support/core_ext/array/wrap'
13
13
  require 'active_support/core_ext/hash/deep_merge'
14
14
  require 'active_support/core_ext/hash/reverse_merge'
15
15
  require 'active_support/core_ext/hash/except'
16
+ require 'active_support/core_ext/hash/slice'
16
17
  require 'active_support/core_ext/hash/conversions'
17
18
  require 'active_support/dependencies/autoload'
18
19
  require 'active_support/notifications'
@@ -198,6 +199,7 @@ require 'grape/util/content_types'
198
199
  require 'grape/validations/validators/base'
199
200
  require 'grape/validations/attributes_iterator'
200
201
  require 'grape/validations/validators/allow_blank'
202
+ require 'grape/validations/validators/as'
201
203
  require 'grape/validations/validators/at_least_one_of'
202
204
  require 'grape/validations/validators/coerce'
203
205
  require 'grape/validations/validators/default'
@@ -50,8 +50,16 @@ module Grape
50
50
  # If it is not a Hash then it does not have children.
51
51
  # Find its value or set it to nil.
52
52
  if !declared_param.is_a?(Hash)
53
- next unless options[:include_missing] || passed_params.key?(declared_param)
54
- memo[optioned_param_key(declared_param, options)] = passed_params[declared_param]
53
+ has_alias = route_setting(:aliased_params) && route_setting(:aliased_params).find { |current| current[declared_param] }
54
+ param_alias = has_alias[declared_param] if has_alias
55
+
56
+ next unless options[:include_missing] || passed_params.key?(declared_param) || param_alias
57
+
58
+ if param_alias
59
+ memo[optioned_param_key(param_alias, options)] = passed_params[param_alias]
60
+ else
61
+ memo[optioned_param_key(declared_param, options)] = passed_params[declared_param]
62
+ end
55
63
  else
56
64
  declared_param.each_pair do |declared_parent_param, declared_children_params|
57
65
  next unless options[:include_missing] || passed_params.key?(declared_parent_param)
@@ -131,8 +131,7 @@ module Grape
131
131
  require_required_and_optional_fields(attrs.first, opts)
132
132
  else
133
133
  validate_attributes(attrs, opts, &block)
134
-
135
- block_given? ? new_scope(orig_attrs, &block) : push_declared_params(attrs)
134
+ block_given? ? new_scope(orig_attrs, &block) : push_declared_params(attrs, opts.slice(:as))
136
135
  end
137
136
  end
138
137
 
@@ -158,7 +157,7 @@ module Grape
158
157
  else
159
158
  validate_attributes(attrs, opts, &block)
160
159
 
161
- block_given? ? new_scope(orig_attrs, true, &block) : push_declared_params(attrs)
160
+ block_given? ? new_scope(orig_attrs, true, &block) : push_declared_params(attrs, opts.slice(:as))
162
161
  end
163
162
  end
164
163
 
@@ -2,7 +2,7 @@ require 'active_support/concern'
2
2
 
3
3
  module Grape
4
4
  module DSL
5
- # Keeps track of settings (impemented as key-value pairs, grouped by
5
+ # Keeps track of settings (implemented as key-value pairs, grouped by
6
6
  # types), in two contexts: top-level settings which apply globally no
7
7
  # matter where they're defined, and inheritable settings which apply only
8
8
  # in the current scope and scopes nested under it.
@@ -13,7 +13,7 @@ module Grape
13
13
 
14
14
  # Fetch our top-level settings, which apply to all endpoints in the API.
15
15
  def top_level_setting
16
- @top_level_setting ||= Grape::Util::InheritableSetting.new
16
+ @top_level_setting ||= build_top_level_setting
17
17
  end
18
18
 
19
19
  # Fetch our current inheritable settings, which are inherited by
@@ -162,6 +162,18 @@ module Grape
162
162
 
163
163
  result
164
164
  end
165
+
166
+ private
167
+
168
+ # Builds the current class :inheritable_setting. If available, it returns the superclass's :inheritable_setting.
169
+ # Otherwise, a clean :inheritable_setting is returned.
170
+ def build_top_level_setting
171
+ if defined?(superclass) && superclass.respond_to?(:inheritable_setting) && superclass != Grape::API
172
+ superclass.inheritable_setting
173
+ else
174
+ Grape::Util::InheritableSetting.new
175
+ end
176
+ end
165
177
  end
166
178
  end
167
179
  end
@@ -4,12 +4,16 @@ module Grape
4
4
  extend Base
5
5
 
6
6
  class << self
7
- def call(message, backtrace, options = {}, env = nil)
7
+ def call(message, backtrace, options = {}, env = nil, original_exception = nil)
8
8
  result = wrap_message(present(message, env))
9
9
 
10
- if (options[:rescue_options] || {})[:backtrace] && backtrace && !backtrace.empty?
10
+ rescue_options = options[:rescue_options] || {}
11
+ if rescue_options[:backtrace] && backtrace && !backtrace.empty?
11
12
  result = result.merge(backtrace: backtrace)
12
13
  end
14
+ if rescue_options[:original_exception] && original_exception
15
+ result = result.merge(original_exception: original_exception.inspect)
16
+ end
13
17
  ::Grape::Json.dump(result)
14
18
  end
15
19
 
@@ -4,14 +4,19 @@ module Grape
4
4
  extend Base
5
5
 
6
6
  class << self
7
- def call(message, backtrace, options = {}, env = nil)
7
+ def call(message, backtrace, options = {}, env = nil, original_exception = nil)
8
8
  message = present(message, env)
9
9
 
10
10
  result = message.is_a?(Hash) ? ::Grape::Json.dump(message) : message
11
- if (options[:rescue_options] || {})[:backtrace] && backtrace && !backtrace.empty?
12
- result += "\r\n "
11
+ rescue_options = options[:rescue_options] || {}
12
+ if rescue_options[:backtrace] && backtrace && !backtrace.empty?
13
+ result += "\r\n backtrace:"
13
14
  result += backtrace.join("\r\n ")
14
15
  end
16
+ if rescue_options[:original_exception] && original_exception
17
+ result += "\r\n original exception:"
18
+ result += "\r\n #{original_exception.inspect}"
19
+ end
15
20
  result
16
21
  end
17
22
  end
@@ -4,13 +4,17 @@ module Grape
4
4
  extend Base
5
5
 
6
6
  class << self
7
- def call(message, backtrace, options = {}, env = nil)
7
+ def call(message, backtrace, options = {}, env = nil, original_exception = nil)
8
8
  message = present(message, env)
9
9
 
10
10
  result = message.is_a?(Hash) ? message : { message: message }
11
- if (options[:rescue_options] || {})[:backtrace] && backtrace && !backtrace.empty?
11
+ rescue_options = options[:rescue_options] || {}
12
+ if rescue_options[:backtrace] && backtrace && !backtrace.empty?
12
13
  result = result.merge(backtrace: backtrace)
13
14
  end
15
+ if rescue_options[:original_exception] && original_exception
16
+ result = result.merge(original_exception: original_exception.inspect)
17
+ end
14
18
  result.respond_to?(:to_xml) ? result.to_xml(root: :error) : result.to_s
15
19
  end
16
20
  end
@@ -14,7 +14,10 @@ module Grape
14
14
  rescue_all: false, # true to rescue all exceptions
15
15
  rescue_grape_exceptions: false,
16
16
  rescue_subclasses: true, # rescue subclasses of exceptions listed
17
- rescue_options: { backtrace: false }, # true to display backtrace, true to let Grape handle Grape::Exceptions
17
+ rescue_options: {
18
+ backtrace: false, # true to display backtrace, true to let Grape handle Grape::Exceptions
19
+ original_exception: false, # true to display exception
20
+ },
18
21
  rescue_handlers: {}, # rescue handler blocks
19
22
  base_only_rescue_handlers: {}, # rescue handler blocks rescuing only the base class
20
23
  all_rescue_handler: nil # rescue handler block to rescue from all exceptions
@@ -77,13 +80,13 @@ module Grape
77
80
  end
78
81
  end
79
82
 
80
- def error!(message, status = options[:default_status], headers = {}, backtrace = [])
83
+ def error!(message, status = options[:default_status], headers = {}, backtrace = [], original_exception = nil)
81
84
  headers = headers.reverse_merge(Grape::Http::Headers::CONTENT_TYPE => content_type)
82
- rack_response(format_message(message, backtrace), status, headers)
85
+ rack_response(format_message(message, backtrace, original_exception), status, headers)
83
86
  end
84
87
 
85
88
  def handle_error(e)
86
- error_response(message: e.message, backtrace: e.backtrace)
89
+ error_response(message: e.message, backtrace: e.backtrace, original_exception: e)
87
90
  end
88
91
 
89
92
  # TODO: This method is deprecated. Refactor out.
@@ -92,19 +95,24 @@ module Grape
92
95
  message = error[:message] || options[:default_message]
93
96
  headers = { Grape::Http::Headers::CONTENT_TYPE => content_type }
94
97
  headers.merge!(error[:headers]) if error[:headers].is_a?(Hash)
95
- backtrace = error[:backtrace] || []
96
- rack_response(format_message(message, backtrace), status, headers)
98
+ backtrace = error[:backtrace] || error[:original_exception] && error[:original_exception].backtrace || []
99
+ original_exception = error.is_a?(Exception) ? error : error[:original_exception] || nil
100
+ rack_response(format_message(message, backtrace, original_exception), status, headers)
97
101
  end
98
102
 
99
103
  def rack_response(message, status = options[:default_status], headers = { Grape::Http::Headers::CONTENT_TYPE => content_type })
100
104
  Rack::Response.new([message], status, headers).finish
101
105
  end
102
106
 
103
- def format_message(message, backtrace)
107
+ def format_message(message, backtrace, original_exception = nil)
104
108
  format = env[Grape::Env::API_FORMAT] || options[:format]
105
109
  formatter = Grape::ErrorFormatter.formatter_for(format, options)
106
- throw :error, status: 406, message: "The requested format '#{format}' is not supported." unless formatter
107
- formatter.call(message, backtrace, options, env)
110
+ throw :error,
111
+ status: 406,
112
+ message: "The requested format '#{format}' is not supported.",
113
+ backtrace: backtrace,
114
+ original_exception: original_exception unless formatter
115
+ formatter.call(message, backtrace, options, env, original_exception)
108
116
  end
109
117
 
110
118
  private