grape 1.8.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/README.md +19 -22
  4. data/UPGRADING.md +35 -0
  5. data/grape.gemspec +1 -4
  6. data/lib/grape/dsl/desc.rb +1 -1
  7. data/lib/grape/dsl/inside_route.rb +9 -9
  8. data/lib/grape/endpoint.rb +9 -1
  9. data/lib/grape/exceptions/missing_group_type.rb +1 -1
  10. data/lib/grape/exceptions/unsupported_group_type.rb +1 -1
  11. data/lib/grape/http/headers.rb +12 -2
  12. data/lib/grape/middleware/auth/strategies.rb +1 -2
  13. data/lib/grape/middleware/error.rb +4 -4
  14. data/lib/grape/middleware/formatter.rb +5 -5
  15. data/lib/grape/railtie.rb +9 -0
  16. data/lib/grape/request.rb +8 -2
  17. data/lib/grape/router/route.rb +1 -1
  18. data/lib/grape/validations/validators/base.rb +1 -1
  19. data/lib/grape/validations/validators/values_validator.rb +2 -2
  20. data/lib/grape/version.rb +1 -1
  21. data/lib/grape.rb +15 -2
  22. metadata +8 -243
  23. data/spec/grape/api/custom_validations_spec.rb +0 -213
  24. data/spec/grape/api/deeply_included_options_spec.rb +0 -56
  25. data/spec/grape/api/defines_boolean_in_params_spec.rb +0 -38
  26. data/spec/grape/api/documentation_spec.rb +0 -59
  27. data/spec/grape/api/inherited_helpers_spec.rb +0 -114
  28. data/spec/grape/api/instance_spec.rb +0 -103
  29. data/spec/grape/api/invalid_format_spec.rb +0 -45
  30. data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -38
  31. data/spec/grape/api/nested_helpers_spec.rb +0 -50
  32. data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -43
  33. data/spec/grape/api/parameters_modification_spec.rb +0 -41
  34. data/spec/grape/api/patch_method_helpers_spec.rb +0 -79
  35. data/spec/grape/api/recognize_path_spec.rb +0 -21
  36. data/spec/grape/api/required_parameters_in_route_spec.rb +0 -37
  37. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -26
  38. data/spec/grape/api/routes_with_requirements_spec.rb +0 -59
  39. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +0 -41
  40. data/spec/grape/api/shared_helpers_spec.rb +0 -36
  41. data/spec/grape/api_remount_spec.rb +0 -509
  42. data/spec/grape/api_spec.rb +0 -4356
  43. data/spec/grape/dsl/callbacks_spec.rb +0 -45
  44. data/spec/grape/dsl/desc_spec.rb +0 -98
  45. data/spec/grape/dsl/headers_spec.rb +0 -62
  46. data/spec/grape/dsl/helpers_spec.rb +0 -100
  47. data/spec/grape/dsl/inside_route_spec.rb +0 -531
  48. data/spec/grape/dsl/logger_spec.rb +0 -24
  49. data/spec/grape/dsl/middleware_spec.rb +0 -60
  50. data/spec/grape/dsl/parameters_spec.rb +0 -180
  51. data/spec/grape/dsl/request_response_spec.rb +0 -225
  52. data/spec/grape/dsl/routing_spec.rb +0 -275
  53. data/spec/grape/dsl/settings_spec.rb +0 -261
  54. data/spec/grape/dsl/validations_spec.rb +0 -55
  55. data/spec/grape/endpoint/declared_spec.rb +0 -846
  56. data/spec/grape/endpoint_spec.rb +0 -1085
  57. data/spec/grape/entity_spec.rb +0 -336
  58. data/spec/grape/exceptions/base_spec.rb +0 -81
  59. data/spec/grape/exceptions/body_parse_errors_spec.rb +0 -185
  60. data/spec/grape/exceptions/invalid_accept_header_spec.rb +0 -358
  61. data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -15
  62. data/spec/grape/exceptions/invalid_response_spec.rb +0 -11
  63. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +0 -15
  64. data/spec/grape/exceptions/missing_group_type_spec.rb +0 -17
  65. data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -17
  66. data/spec/grape/exceptions/missing_option_spec.rb +0 -15
  67. data/spec/grape/exceptions/unknown_options_spec.rb +0 -15
  68. data/spec/grape/exceptions/unknown_validator_spec.rb +0 -15
  69. data/spec/grape/exceptions/unsupported_group_type_spec.rb +0 -19
  70. data/spec/grape/exceptions/validation_errors_spec.rb +0 -92
  71. data/spec/grape/exceptions/validation_spec.rb +0 -19
  72. data/spec/grape/extensions/param_builders/hash_spec.rb +0 -83
  73. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +0 -105
  74. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +0 -79
  75. data/spec/grape/grape_spec.rb +0 -9
  76. data/spec/grape/integration/global_namespace_function_spec.rb +0 -29
  77. data/spec/grape/integration/rack_sendfile_spec.rb +0 -48
  78. data/spec/grape/integration/rack_spec.rb +0 -51
  79. data/spec/grape/loading_spec.rb +0 -44
  80. data/spec/grape/middleware/auth/base_spec.rb +0 -31
  81. data/spec/grape/middleware/auth/dsl_spec.rb +0 -60
  82. data/spec/grape/middleware/auth/strategies_spec.rb +0 -120
  83. data/spec/grape/middleware/base_spec.rb +0 -221
  84. data/spec/grape/middleware/error_spec.rb +0 -85
  85. data/spec/grape/middleware/exception_spec.rb +0 -294
  86. data/spec/grape/middleware/formatter_spec.rb +0 -461
  87. data/spec/grape/middleware/globals_spec.rb +0 -30
  88. data/spec/grape/middleware/stack_spec.rb +0 -155
  89. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +0 -122
  90. data/spec/grape/middleware/versioner/header_spec.rb +0 -345
  91. data/spec/grape/middleware/versioner/param_spec.rb +0 -171
  92. data/spec/grape/middleware/versioner/path_spec.rb +0 -62
  93. data/spec/grape/middleware/versioner_spec.rb +0 -21
  94. data/spec/grape/named_api_spec.rb +0 -19
  95. data/spec/grape/parser_spec.rb +0 -86
  96. data/spec/grape/path_spec.rb +0 -252
  97. data/spec/grape/presenters/presenter_spec.rb +0 -71
  98. data/spec/grape/request_spec.rb +0 -126
  99. data/spec/grape/util/inheritable_setting_spec.rb +0 -242
  100. data/spec/grape/util/inheritable_values_spec.rb +0 -79
  101. data/spec/grape/util/reverse_stackable_values_spec.rb +0 -134
  102. data/spec/grape/util/stackable_values_spec.rb +0 -128
  103. data/spec/grape/util/strict_hash_configuration_spec.rb +0 -38
  104. data/spec/grape/validations/attributes_doc_spec.rb +0 -153
  105. data/spec/grape/validations/instance_behaivour_spec.rb +0 -43
  106. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +0 -38
  107. data/spec/grape/validations/params_scope_spec.rb +0 -1420
  108. data/spec/grape/validations/single_attribute_iterator_spec.rb +0 -56
  109. data/spec/grape/validations/types/array_coercer_spec.rb +0 -33
  110. data/spec/grape/validations/types/primitive_coercer_spec.rb +0 -150
  111. data/spec/grape/validations/types/set_coercer_spec.rb +0 -32
  112. data/spec/grape/validations/types_spec.rb +0 -111
  113. data/spec/grape/validations/validators/all_or_none_spec.rb +0 -162
  114. data/spec/grape/validations/validators/allow_blank_spec.rb +0 -575
  115. data/spec/grape/validations/validators/at_least_one_of_spec.rb +0 -205
  116. data/spec/grape/validations/validators/base_spec.rb +0 -38
  117. data/spec/grape/validations/validators/coerce_spec.rb +0 -1261
  118. data/spec/grape/validations/validators/default_spec.rb +0 -463
  119. data/spec/grape/validations/validators/exactly_one_of_spec.rb +0 -233
  120. data/spec/grape/validations/validators/except_values_spec.rb +0 -192
  121. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +0 -214
  122. data/spec/grape/validations/validators/presence_spec.rb +0 -315
  123. data/spec/grape/validations/validators/regexp_spec.rb +0 -161
  124. data/spec/grape/validations/validators/same_as_spec.rb +0 -57
  125. data/spec/grape/validations/validators/values_spec.rb +0 -733
  126. data/spec/grape/validations/validators/zh-CN.yml +0 -10
  127. data/spec/grape/validations_spec.rb +0 -2030
  128. data/spec/integration/eager_load/eager_load_spec.rb +0 -15
  129. data/spec/integration/multi_json/json_spec.rb +0 -7
  130. data/spec/integration/multi_xml/xml_spec.rb +0 -7
  131. data/spec/shared/deprecated_class_examples.rb +0 -16
  132. data/spec/shared/versioning_examples.rb +0 -215
  133. data/spec/spec_helper.rb +0 -52
  134. data/spec/support/basic_auth_encode_helpers.rb +0 -11
  135. data/spec/support/chunks.rb +0 -14
  136. data/spec/support/content_type_helpers.rb +0 -15
  137. data/spec/support/endpoint_faker.rb +0 -25
  138. data/spec/support/file_streamer.rb +0 -13
  139. data/spec/support/integer_helpers.rb +0 -13
  140. data/spec/support/versioned_helpers.rb +0 -55
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac7bd232782ed265b59ec7f4ea0dec03a0896b328694ebe1507cf9680e1bee41
4
- data.tar.gz: b81cb45c2b6daab5b413af0df615a542907c9fbf1732e3fc46347321dedc4f65
3
+ metadata.gz: 4983aa4cc8cb0085312902cb28ced60d0e8ff0762821f50027adec6e66f4f75a
4
+ data.tar.gz: 1b22ed94c6e526aa8485f4e27ae4cde775ae424018805544620008b090054c7e
5
5
  SHA512:
6
- metadata.gz: 1929a95447ec3923443e908a8240195e7e4a0f5a3113f8679e947cc3813e800f45f35c928dfef9495ff277a983bf3bdcb4ca358ab889e28224d890a3d078d7de
7
- data.tar.gz: 4d5141c1f331ee07eaa78bd89e1b76f99b6cbcb7d6f0dda3f12f9e6b900c977c9a0757c0d912a6cd53ea5ef9bce8409a211c4a77c4b78a0f5e607ecd1e055480
6
+ metadata.gz: 7680cff51b187ef4f941a8e1596af52ee79b6631da12670e3031eeb79470e2f15a681c3f19406ecdca63e21ad9e2dbcc8362bc4f86c36647940305786f7f082e
7
+ data.tar.gz: 00dc6bd81800ddaf0638ddc8619a6989f3560b38344807a9058bb470c6ecaa29108e52b9104edafdfb1afd4ee70d98c73a9a51db9a6df9081eb42820a2e25773
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ### 2.0.0 (2023/11/11)
2
+
3
+ #### Features
4
+
5
+ * [#2353](https://github.com/ruby-grape/grape/pull/2353): Added Rails 7.1 support - [@ericproulx](https://github.com/ericproulx).
6
+ * [#2355](https://github.com/ruby-grape/grape/pull/2355): Set response headers based on Rack version - [@schinery](https://github.com/schinery).
7
+ * [#2360](https://github.com/ruby-grape/grape/pull/2360): Reduce gem size by removing specs - [@ericproulx](https://github.com/ericproulx).
8
+ * [#2361](https://github.com/ruby-grape/grape/pull/2361): Remove `Rack::Auth::Digest` - [@ninoseki](https://github.com/ninoseki).
9
+
10
+ #### Fixes
11
+
12
+ * [#2364](https://github.com/ruby-grape/grape/pull/2364): Add missing requires - [@ericproulx](https://github.com/ericproulx).
13
+ * [#2366](https://github.com/ruby-grape/grape/pull/2366): Default quality to 1.0 in the `Accept` header when omitted - [@hiddewie](https://github.com/hiddewie).
14
+ * [#2368](https://github.com/ruby-grape/grape/pull/2368): Stripping the internals of `Grape::Endpoint` when `NoMethodError` is raised - [@jcagarcia](https://github.com/jcagarcia).
15
+
1
16
  ### 1.8.0 (2023/08/30)
2
17
 
3
18
  #### Features
data/README.md CHANGED
@@ -15,6 +15,7 @@
15
15
  - [Grape for Enterprise](#grape-for-enterprise)
16
16
  - [Installation](#installation)
17
17
  - [Basic Usage](#basic-usage)
18
+ - [Rails 7.1](#rails-71)
18
19
  - [Mounting](#mounting)
19
20
  - [All](#all)
20
21
  - [Rack](#rack)
@@ -114,7 +115,7 @@
114
115
  - [Active Model Serializers](#active-model-serializers)
115
116
  - [Sending Raw or No Data](#sending-raw-or-no-data)
116
117
  - [Authentication](#authentication)
117
- - [Basic and Digest Auth](#basic-and-digest-auth)
118
+ - [Basic Auth](#basic-auth)
118
119
  - [Register custom middleware for authentication](#register-custom-middleware-for-authentication)
119
120
  - [Describing and Inspecting an API](#describing-and-inspecting-an-api)
120
121
  - [Current Route and Endpoint](#current-route-and-endpoint)
@@ -159,9 +160,10 @@ content negotiation, versioning and much more.
159
160
 
160
161
  ## Stable Release
161
162
 
162
- You're reading the documentation for the stable release of Grape, **1.8.0**.
163
+ You're reading the documentation for the stable release of Grape, **2.0.0**.
163
164
  Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
164
165
 
166
+
165
167
  ## Project Resources
166
168
 
167
169
  * [Grape Website](http://www.ruby-grape.org)
@@ -177,7 +179,7 @@ The maintainers of Grape are working with Tidelift to deliver commercial support
177
179
 
178
180
  ## Installation
179
181
 
180
- Ruby 2.4 or newer is required.
182
+ Ruby 2.6 or newer is required.
181
183
 
182
184
  Grape is available as a gem, to install it run:
183
185
 
@@ -266,6 +268,10 @@ module Twitter
266
268
  end
267
269
  ```
268
270
 
271
+ ## Rails 7.1
272
+
273
+ Grape's [deprecator](https://api.rubyonrails.org/v7.1.0/classes/ActiveSupport/Deprecation.html) will be added to your application's deprecators [automatically](lib/grape/railtie.rb) as `:grape`, so that your application's configuration can be applied to it.
274
+
269
275
  ## Mounting
270
276
 
271
277
  ### All
@@ -589,6 +595,10 @@ When an invalid `Accept` header is supplied, a `406 Not Acceptable` error is ret
589
595
  option is set to `false`. Otherwise a `404 Not Found` error is returned by Rack if no other route
590
596
  matches.
591
597
 
598
+ Grape will evaluate the relative quality preference included in Accept headers and default to a quality of 1.0 when omitted. In the following example a Grape API that supports XML and JSON in that order will return JSON:
599
+
600
+ curl -H "Accept: text/xml;q=0.8, application/json;q=0.9" localhost:1234/resource
601
+
592
602
  ### Accept-Version Header
593
603
 
594
604
  ```ruby
@@ -1593,7 +1603,7 @@ Note endless ranges are also supported with ActiveSupport >= 6.0, but they requi
1593
1603
  ```ruby
1594
1604
  params do
1595
1605
  requires :minimum, type: Integer, values: 10..
1596
- optional :maximum, type: Integer, values: ..10
1606
+ optional :maximum, type: Integer, values: ..10
1597
1607
  end
1598
1608
  ```
1599
1609
 
@@ -2123,8 +2133,9 @@ curl -H "secret_PassWord: swordfish" ...
2123
2133
 
2124
2134
  The header name will have been normalized for you.
2125
2135
 
2126
- - In the `header` helper names will be coerced into a capitalized kebab case.
2127
- - In the `env` collection they appear in all uppercase, in snake case, and prefixed with 'HTTP_'.
2136
+ - In the `header` helper names will be coerced into a downcased kebab case as `secret-password` if using Rack 3.
2137
+ - In the `header` helper names will be coerced into a capitalized kebab case as `Secret-PassWord` if using Rack < 3.
2138
+ - In the `env` collection they appear in all uppercase, in snake case, and prefixed with 'HTTP_' as `HTTP_SECRET_PASSWORD`
2128
2139
 
2129
2140
  The header name will have been normalized per HTTP standards defined in [RFC2616 Section 4.2](https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2) regardless of what is being sent by a client.
2130
2141
 
@@ -3414,9 +3425,9 @@ end
3414
3425
 
3415
3426
  ## Authentication
3416
3427
 
3417
- ### Basic and Digest Auth
3428
+ ### Basic Auth
3418
3429
 
3419
- Grape has built-in Basic and Digest authentication (the given `block`
3430
+ Grape has built-in Basic authentication (the given `block`
3420
3431
  is executed in the context of the current `Endpoint`). Authentication
3421
3432
  applies to the current namespace and any children, but not parents.
3422
3433
 
@@ -3427,20 +3438,6 @@ http_basic do |username, password|
3427
3438
  end
3428
3439
  ```
3429
3440
 
3430
- Digest auth supports clear-text passwords and password hashes.
3431
-
3432
- ```ruby
3433
- http_digest({ realm: 'Test Api', opaque: 'app secret' }) do |username|
3434
- # lookup the user's password here
3435
- end
3436
- ```
3437
-
3438
- ```ruby
3439
- http_digest(realm: { realm: 'Test Api', opaque: 'app secret', passwords_hashed: true }) do |username|
3440
- # lookup the user's password hash here
3441
- end
3442
- ```
3443
-
3444
3441
  ### Register custom middleware for authentication
3445
3442
 
3446
3443
  Grape can use custom Middleware for authentication. How to implement these
data/UPGRADING.md CHANGED
@@ -1,6 +1,41 @@
1
1
  Upgrading Grape
2
2
  ===============
3
3
 
4
+ ### Upgrading to >= 2.0.0
5
+
6
+ #### Headers
7
+
8
+ As per [rack/rack#1592](https://github.com/rack/rack/issues/1592) Rack 3 is following the HTTP/2+ semantics which require header names to be lower case. To avoid compatibility issues, starting with Grape 1.9.0, headers will be cased based on what version of Rack you are using.
9
+
10
+ Given this request:
11
+
12
+ ```shell
13
+ curl -H "Content-Type: application/json" -H "Secret-Password: foo" ...
14
+ ```
15
+
16
+ If you are using Rack 3 in your application then the headers will be set to:
17
+
18
+ ```ruby
19
+ { "content-type" => "application/json", "secret-password" => "foo"}
20
+ ```
21
+
22
+ This means if you are checking for header values in your application, you would need to change your code to use downcased keys.
23
+
24
+ ```ruby
25
+ get do
26
+ # This would use headers['Secret-Password'] in Rack < 3
27
+ error!('Unauthorized', 401) unless headers['secret-password'] == 'swordfish'
28
+ end
29
+ ```
30
+
31
+ See [#2355](https://github.com/ruby-grape/grape/pull/2355) for more information.
32
+
33
+ #### Digest auth deprecation
34
+
35
+ Digest auth has been removed along with the deprecation of `Rack::Auth::Digest` in Rack 3.
36
+
37
+ See [#2294](https://github.com/ruby-grape/grape/issues/2294) for more information.
38
+
4
39
  ### Upgrading to >= 1.7.0
5
40
 
6
41
  #### Exceptions renaming
data/grape.gemspec CHANGED
@@ -27,10 +27,7 @@ Gem::Specification.new do |s|
27
27
  s.add_runtime_dependency 'rack', '>= 1.3.0'
28
28
  s.add_runtime_dependency 'rack-accept'
29
29
 
30
- s.files = %w[CHANGELOG.md CONTRIBUTING.md README.md grape.png UPGRADING.md LICENSE]
31
- s.files += %w[grape.gemspec]
32
- s.files += Dir['lib/**/*']
33
- s.test_files = Dir['spec/**/*']
30
+ s.files = Dir['lib/**/*', 'CHANGELOG.md', 'CONTRIBUTING.md', 'README.md', 'grape.png', 'UPGRADING.md', 'LICENSE', 'grape.gemspec']
34
31
  s.require_paths = ['lib']
35
32
  s.required_ruby_version = '>= 2.6.0'
36
33
  end
@@ -68,7 +68,7 @@ module Grape
68
68
  end
69
69
 
70
70
  config_class.configure(&config_block)
71
- ActiveSupport::Deprecation.warn('Passing a options hash and a block to `desc` is deprecated. Move all hash options to block.') if options.any?
71
+ Grape.deprecator.warn('Passing a options hash and a block to `desc` is deprecated. Move all hash options to block.') if options.any?
72
72
  options = config_class.settings
73
73
  else
74
74
  options = options.merge(description: description)
@@ -185,7 +185,7 @@ module Grape
185
185
  status 302
186
186
  body_message ||= "This resource has been moved temporarily to #{url}."
187
187
  end
188
- header 'Location', url
188
+ header Grape::Http::Headers::LOCATION, url
189
189
  content_type 'text/plain'
190
190
  body body_message
191
191
  end
@@ -224,9 +224,9 @@ module Grape
224
224
  # Set response content-type
225
225
  def content_type(val = nil)
226
226
  if val
227
- header(Grape::Http::Headers::CONTENT_TYPE, val)
227
+ header(Rack::CONTENT_TYPE, val)
228
228
  else
229
- header[Grape::Http::Headers::CONTENT_TYPE]
229
+ header[Rack::CONTENT_TYPE]
230
230
  end
231
231
  end
232
232
 
@@ -280,13 +280,13 @@ module Grape
280
280
  # Deprecated method to send files to the client. Use `sendfile` or `stream`
281
281
  def file(value = nil)
282
282
  if value.is_a?(String)
283
- ActiveSupport::Deprecation.warn('Use sendfile or stream to send files.')
283
+ Grape.deprecator.warn('Use sendfile or stream to send files.')
284
284
  sendfile(value)
285
285
  elsif !value.is_a?(NilClass)
286
- ActiveSupport::Deprecation.warn('Use stream to use a Stream object.')
286
+ Grape.deprecator.warn('Use stream to use a Stream object.')
287
287
  stream(value)
288
288
  else
289
- ActiveSupport::Deprecation.warn('Use sendfile or stream to send files.')
289
+ Grape.deprecator.warn('Use sendfile or stream to send files.')
290
290
  sendfile
291
291
  end
292
292
  end
@@ -328,9 +328,9 @@ module Grape
328
328
  def stream(value = nil)
329
329
  return if value.nil? && @stream.nil?
330
330
 
331
- header 'Content-Length', nil
332
- header 'Transfer-Encoding', nil
333
- header 'Cache-Control', 'no-cache' # Skips ETag generation (reading the response up front)
331
+ header Rack::CONTENT_LENGTH, nil
332
+ header Grape::Http::Headers::TRANSFER_ENCODING, nil
333
+ header Rack::CACHE_CONTROL, 'no-cache' # Skips ETag generation (reading the response up front)
334
334
  if value.is_a?(String)
335
335
  file_body = Grape::ServeStream::FileBody.new(value)
336
336
  @stream = Grape::ServeStream::StreamResponse.new(file_body)
@@ -250,7 +250,7 @@ module Grape
250
250
  if (allowed_methods = env[Grape::Env::GRAPE_ALLOWED_METHODS])
251
251
  raise Grape::Exceptions::MethodNotAllowed.new(header.merge('Allow' => allowed_methods)) unless options?
252
252
 
253
- header 'Allow', allowed_methods
253
+ header Grape::Http::Headers::ALLOW, allowed_methods
254
254
  response_object = ''
255
255
  status 204
256
256
  else
@@ -403,5 +403,13 @@ module Grape
403
403
  options[:options_route_enabled] &&
404
404
  env[Grape::Http::Headers::REQUEST_METHOD] == Grape::Http::Headers::OPTIONS
405
405
  end
406
+
407
+ def method_missing(name, *_args)
408
+ raise NoMethodError.new("undefined method `#{name}' for #{self.class} in `#{route.origin}' endpoint")
409
+ end
410
+
411
+ def respond_to_missing?(method_name, include_private = false)
412
+ super
413
+ end
406
414
  end
407
415
  end
@@ -10,4 +10,4 @@ module Grape
10
10
  end
11
11
  end
12
12
 
13
- Grape::Exceptions::MissingGroupTypeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Grape::Exceptions::MissingGroupTypeError', 'Grape::Exceptions::MissingGroupType')
13
+ Grape::Exceptions::MissingGroupTypeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Grape::Exceptions::MissingGroupTypeError', 'Grape::Exceptions::MissingGroupType', Grape.deprecator)
@@ -10,4 +10,4 @@ module Grape
10
10
  end
11
11
  end
12
12
 
13
- Grape::Exceptions::UnsupportedGroupTypeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Grape::Exceptions::UnsupportedGroupTypeError', 'Grape::Exceptions::UnsupportedGroupType')
13
+ Grape::Exceptions::UnsupportedGroupTypeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Grape::Exceptions::UnsupportedGroupTypeError', 'Grape::Exceptions::UnsupportedGroupType', Grape.deprecator)
@@ -10,7 +10,18 @@ module Grape
10
10
  PATH_INFO = 'PATH_INFO'
11
11
  REQUEST_METHOD = 'REQUEST_METHOD'
12
12
  QUERY_STRING = 'QUERY_STRING'
13
- CONTENT_TYPE = 'Content-Type'
13
+
14
+ if Grape.lowercase_headers?
15
+ ALLOW = 'allow'
16
+ LOCATION = 'location'
17
+ TRANSFER_ENCODING = 'transfer-encoding'
18
+ X_CASCADE = 'x-cascade'
19
+ else
20
+ ALLOW = 'Allow'
21
+ LOCATION = 'Location'
22
+ TRANSFER_ENCODING = 'Transfer-Encoding'
23
+ X_CASCADE = 'X-Cascade'
24
+ end
14
25
 
15
26
  GET = 'GET'
16
27
  POST = 'POST'
@@ -24,7 +35,6 @@ module Grape
24
35
  SUPPORTED_METHODS_WITHOUT_OPTIONS = Grape::Util::LazyObject.new { [GET, POST, PUT, PATCH, DELETE, HEAD].freeze }
25
36
 
26
37
  HTTP_ACCEPT_VERSION = 'HTTP_ACCEPT_VERSION'
27
- X_CASCADE = 'X-Cascade'
28
38
  HTTP_TRANSFER_ENCODING = 'HTTP_TRANSFER_ENCODING'
29
39
  HTTP_ACCEPT = 'HTTP_ACCEPT'
30
40
 
@@ -12,8 +12,7 @@ module Grape
12
12
 
13
13
  def auth_strategies
14
14
  @auth_strategies ||= {
15
- http_basic: StrategyInfo.new(Rack::Auth::Basic, ->(settings) { [settings[:realm]] }),
16
- http_digest: StrategyInfo.new(Rack::Auth::Digest::MD5, ->(settings) { [settings[:realm], settings[:opaque]] })
15
+ http_basic: StrategyInfo.new(Rack::Auth::Basic, ->(settings) { [settings[:realm]] })
17
16
  }
18
17
  end
19
18
 
@@ -51,7 +51,7 @@ module Grape
51
51
  end
52
52
 
53
53
  def error!(message, status = options[:default_status], headers = {}, backtrace = [], original_exception = nil)
54
- headers = headers.reverse_merge(Grape::Http::Headers::CONTENT_TYPE => content_type)
54
+ headers = headers.reverse_merge(Rack::CONTENT_TYPE => content_type)
55
55
  rack_response(format_message(message, backtrace, original_exception), status, headers)
56
56
  end
57
57
 
@@ -63,15 +63,15 @@ module Grape
63
63
  def error_response(error = {})
64
64
  status = error[:status] || options[:default_status]
65
65
  message = error[:message] || options[:default_message]
66
- headers = { Grape::Http::Headers::CONTENT_TYPE => content_type }
66
+ headers = { Rack::CONTENT_TYPE => content_type }
67
67
  headers.merge!(error[:headers]) if error[:headers].is_a?(Hash)
68
68
  backtrace = error[:backtrace] || error[:original_exception]&.backtrace || []
69
69
  original_exception = error.is_a?(Exception) ? error : error[:original_exception] || nil
70
70
  rack_response(format_message(message, backtrace, original_exception), status, headers)
71
71
  end
72
72
 
73
- def rack_response(message, status = options[:default_status], headers = { Grape::Http::Headers::CONTENT_TYPE => content_type })
74
- message = ERB::Util.html_escape(message) if headers[Grape::Http::Headers::CONTENT_TYPE] == TEXT_HTML
73
+ def rack_response(message, status = options[:default_status], headers = { Rack::CONTENT_TYPE => content_type })
74
+ message = ERB::Util.html_escape(message) if headers[Rack::CONTENT_TYPE] == TEXT_HTML
75
75
  Rack::Response.new([message], Rack::Utils.status_code(status), headers)
76
76
  end
77
77
 
@@ -54,7 +54,7 @@ module Grape
54
54
  end
55
55
 
56
56
  def fetch_formatter(headers, options)
57
- api_format = mime_types[headers[Grape::Http::Headers::CONTENT_TYPE]] || env[Grape::Env::API_FORMAT]
57
+ api_format = mime_types[headers[Rack::CONTENT_TYPE]] || env[Grape::Env::API_FORMAT]
58
58
  Grape::Formatter.formatter_for(api_format, **options)
59
59
  end
60
60
 
@@ -63,10 +63,10 @@ module Grape
63
63
  # @param headers [Hash]
64
64
  # @return [Hash]
65
65
  def ensure_content_type(headers)
66
- if headers[Grape::Http::Headers::CONTENT_TYPE]
66
+ if headers[Rack::CONTENT_TYPE]
67
67
  headers
68
68
  else
69
- headers.merge(Grape::Http::Headers::CONTENT_TYPE => content_type_for(env[Grape::Env::API_FORMAT]))
69
+ headers.merge(Rack::CONTENT_TYPE => content_type_for(env[Grape::Env::API_FORMAT]))
70
70
  end
71
71
  end
72
72
 
@@ -164,14 +164,14 @@ module Grape
164
164
  \w+/[\w+.-]+) # eg application/vnd.example.myformat+xml
165
165
  (?:
166
166
  (?:;[^,]*?)? # optionally multiple formats in a row
167
- ;\s*q=([\d.]+) # optional "quality" preference (eg q=0.5)
167
+ ;\s*q=([\w.]+) # optional "quality" preference (eg q=0.5)
168
168
  )?
169
169
  }x
170
170
 
171
171
  vendor_prefix_pattern = /vnd\.[^+]+\+/
172
172
 
173
173
  accept.scan(accept_into_mime_and_quality)
174
- .sort_by { |_, quality_preference| -quality_preference.to_f }
174
+ .sort_by { |_, quality_preference| -(quality_preference ? quality_preference.to_f : 1.0) }
175
175
  .flat_map { |mime, _| [mime, mime.sub(vendor_prefix_pattern, '')] }
176
176
  end
177
177
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ class Railtie < ::Rails::Railtie
5
+ initializer 'grape.deprecator' do |app|
6
+ app.deprecators[:grape] = Grape.deprecator
7
+ end
8
+ end
9
+ end
data/lib/grape/request.rb CHANGED
@@ -46,8 +46,14 @@ module Grape
46
46
  end
47
47
  end
48
48
 
49
- def transform_header(header)
50
- -header[5..].split('_').each(&:capitalize!).join('-')
49
+ if Grape.lowercase_headers?
50
+ def transform_header(header)
51
+ -header[5..].tr('_', '-').downcase
52
+ end
53
+ else
54
+ def transform_header(header)
55
+ -header[5..].split('_').map(&:capitalize).join('-')
56
+ end
51
57
  end
52
58
  end
53
59
  end
@@ -84,7 +84,7 @@ module Grape
84
84
  path, line = *location.scan(SOURCE_LOCATION_REGEXP).first
85
85
  path = File.realpath(path) if Pathname.new(path).relative?
86
86
  expected ||= name
87
- ActiveSupport::Deprecation.warn("#{path}:#{line}: The route_xxx methods such as route_#{name} have been deprecated, please use #{expected}.")
87
+ Grape.deprecator.warn("#{path}:#{line}: The route_xxx methods such as route_#{name} have been deprecated, please use #{expected}.")
88
88
  end
89
89
  end
90
90
  end
@@ -85,7 +85,7 @@ end
85
85
 
86
86
  Grape::Validations::Base = Class.new(Grape::Validations::Validators::Base) do
87
87
  def self.inherited(*)
88
- ActiveSupport::Deprecation.warn 'Grape::Validations::Base is deprecated! Use Grape::Validations::Validators::Base instead.'
88
+ Grape.deprecator.warn 'Grape::Validations::Base is deprecated! Use Grape::Validations::Validators::Base instead.'
89
89
  super
90
90
  end
91
91
  end
@@ -10,11 +10,11 @@ module Grape
10
10
  @values = options[:value]
11
11
  @proc = options[:proc]
12
12
 
13
- ActiveSupport::Deprecation.warn('The values validator except option is deprecated. Use the except validator instead.') if @excepts
13
+ Grape.deprecator.warn('The values validator except option is deprecated. Use the except validator instead.') if @excepts
14
14
 
15
15
  raise ArgumentError, 'proc must be a Proc' if @proc && !@proc.is_a?(Proc)
16
16
 
17
- ActiveSupport::Deprecation.warn('The values validator proc option is deprecated. The lambda expression can now be assigned directly to values.') if @proc
17
+ Grape.deprecator.warn('The values validator proc option is deprecated. The lambda expression can now be assigned directly to values.') if @proc
18
18
  else
19
19
  @excepts = nil
20
20
  @values = nil
data/lib/grape/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Grape
4
4
  # The current version of Grape.
5
- VERSION = '1.8.0'
5
+ VERSION = '2.0.0'
6
6
  end
data/lib/grape.rb CHANGED
@@ -5,7 +5,6 @@ require 'rack'
5
5
  require 'rack/builder'
6
6
  require 'rack/accept'
7
7
  require 'rack/auth/basic'
8
- require 'rack/auth/digest/md5'
9
8
  require 'set'
10
9
  require 'bigdecimal'
11
10
  require 'date'
@@ -17,6 +16,7 @@ require 'active_support/isolated_execution_state' if ActiveSupport::VERSION::MAJ
17
16
  require 'active_support/core_ext/array/conversions'
18
17
  require 'active_support/core_ext/array/extract_options'
19
18
  require 'active_support/core_ext/array/wrap'
19
+ require 'active_support/core_ext/enumerable'
20
20
  require 'active_support/core_ext/hash/conversions'
21
21
  require 'active_support/core_ext/hash/deep_merge'
22
22
  require 'active_support/core_ext/hash/except'
@@ -25,7 +25,9 @@ require 'active_support/core_ext/hash/keys'
25
25
  require 'active_support/core_ext/hash/reverse_merge'
26
26
  require 'active_support/core_ext/hash/slice'
27
27
  require 'active_support/core_ext/object/blank'
28
+ require 'active_support/core_ext/object/deep_dup'
28
29
  require 'active_support/core_ext/object/duplicable'
30
+ require 'active_support/core_ext/string/exclude'
29
31
  require 'active_support/dependencies/autoload'
30
32
  require 'active_support/deprecation'
31
33
  require 'active_support/inflector'
@@ -38,6 +40,14 @@ module Grape
38
40
  include ActiveSupport::Configurable
39
41
  extend ::ActiveSupport::Autoload
40
42
 
43
+ def self.deprecator
44
+ @deprecator ||= ActiveSupport::Deprecation.new('2.0', 'Grape')
45
+ end
46
+
47
+ def self.lowercase_headers?
48
+ Rack::CONTENT_TYPE == 'content-type'
49
+ end
50
+
41
51
  eager_autoload do
42
52
  autoload :API
43
53
  autoload :Endpoint
@@ -301,5 +311,8 @@ require 'grape/content_types'
301
311
  require 'grape/util/lazy_value'
302
312
  require 'grape/util/lazy_block'
303
313
  require 'grape/util/endpoint_configuration'
304
-
305
314
  require 'grape/version'
315
+
316
+ # https://api.rubyonrails.org/classes/ActiveSupport/Deprecation.html
317
+ # adding Grape.deprecator to Rails App if any
318
+ require 'grape/railtie' if defined?(Rails::Railtie) && ActiveSupport.gem_version >= Gem::Version.new('7.1')