grape 1.8.0 → 2.0.0

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 (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')