grape 1.1.0 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (306) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +370 -44
  3. data/CONTRIBUTING.md +32 -1
  4. data/LICENSE +1 -1
  5. data/README.md +683 -87
  6. data/UPGRADING.md +481 -17
  7. data/grape.gemspec +15 -4
  8. data/lib/grape/api/helpers.rb +2 -0
  9. data/lib/grape/api/instance.rb +279 -0
  10. data/lib/grape/api.rb +144 -176
  11. data/lib/grape/config.rb +34 -0
  12. data/lib/grape/content_types.rb +34 -0
  13. data/lib/grape/cookies.rb +4 -0
  14. data/lib/grape/dry_types.rb +12 -0
  15. data/lib/grape/dsl/api.rb +1 -1
  16. data/lib/grape/dsl/callbacks.rb +21 -1
  17. data/lib/grape/dsl/configuration.rb +1 -1
  18. data/lib/grape/dsl/desc.rb +41 -23
  19. data/lib/grape/dsl/headers.rb +7 -2
  20. data/lib/grape/dsl/helpers.rb +10 -7
  21. data/lib/grape/dsl/inside_route.rb +118 -62
  22. data/lib/grape/dsl/logger.rb +2 -0
  23. data/lib/grape/dsl/middleware.rb +11 -4
  24. data/lib/grape/dsl/parameters.rb +33 -19
  25. data/lib/grape/dsl/request_response.rb +12 -9
  26. data/lib/grape/dsl/routing.rb +22 -13
  27. data/lib/grape/dsl/settings.rb +10 -6
  28. data/lib/grape/dsl/validations.rb +19 -14
  29. data/lib/grape/eager_load.rb +20 -0
  30. data/lib/grape/endpoint.rb +67 -58
  31. data/lib/grape/error_formatter/base.rb +2 -0
  32. data/lib/grape/error_formatter/json.rb +11 -7
  33. data/lib/grape/error_formatter/txt.rb +2 -0
  34. data/lib/grape/error_formatter/xml.rb +4 -6
  35. data/lib/grape/error_formatter.rb +4 -2
  36. data/lib/grape/exceptions/base.rb +23 -16
  37. data/lib/grape/exceptions/empty_message_body.rb +11 -0
  38. data/lib/grape/exceptions/incompatible_option_values.rb +2 -0
  39. data/lib/grape/exceptions/invalid_accept_header.rb +2 -0
  40. data/lib/grape/exceptions/invalid_formatter.rb +2 -0
  41. data/lib/grape/exceptions/invalid_message_body.rb +2 -0
  42. data/lib/grape/exceptions/invalid_response.rb +11 -0
  43. data/lib/grape/exceptions/invalid_version_header.rb +2 -0
  44. data/lib/grape/exceptions/invalid_versioner_option.rb +2 -0
  45. data/lib/grape/exceptions/invalid_with_option_for_represent.rb +2 -0
  46. data/lib/grape/exceptions/method_not_allowed.rb +2 -0
  47. data/lib/grape/exceptions/missing_group_type.rb +10 -1
  48. data/lib/grape/exceptions/missing_mime_type.rb +2 -0
  49. data/lib/grape/exceptions/missing_option.rb +2 -0
  50. data/lib/grape/exceptions/missing_vendor_option.rb +2 -0
  51. data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
  52. data/lib/grape/exceptions/unknown_options.rb +2 -0
  53. data/lib/grape/exceptions/unknown_parameter.rb +2 -0
  54. data/lib/grape/exceptions/unknown_validator.rb +2 -0
  55. data/lib/grape/exceptions/unsupported_group_type.rb +10 -1
  56. data/lib/grape/exceptions/validation.rb +5 -8
  57. data/lib/grape/exceptions/validation_array_errors.rb +2 -0
  58. data/lib/grape/exceptions/validation_errors.rb +16 -13
  59. data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +4 -3
  60. data/lib/grape/extensions/deep_mergeable_hash.rb +2 -0
  61. data/lib/grape/extensions/deep_symbolize_hash.rb +2 -0
  62. data/lib/grape/extensions/hash.rb +2 -0
  63. data/lib/grape/extensions/hashie/mash.rb +2 -0
  64. data/lib/grape/formatter/json.rb +3 -0
  65. data/lib/grape/formatter/serializable_hash.rb +4 -1
  66. data/lib/grape/formatter/txt.rb +2 -0
  67. data/lib/grape/formatter/xml.rb +3 -0
  68. data/lib/grape/formatter.rb +5 -3
  69. data/lib/grape/http/headers.rb +50 -18
  70. data/lib/grape/locale/en.yml +11 -8
  71. data/lib/grape/middleware/auth/base.rb +7 -7
  72. data/lib/grape/middleware/auth/dsl.rb +9 -2
  73. data/lib/grape/middleware/auth/strategies.rb +2 -0
  74. data/lib/grape/middleware/auth/strategy_info.rb +2 -0
  75. data/lib/grape/middleware/base.rb +13 -8
  76. data/lib/grape/middleware/error.rb +22 -17
  77. data/lib/grape/middleware/filter.rb +2 -0
  78. data/lib/grape/middleware/formatter.rb +12 -10
  79. data/lib/grape/middleware/globals.rb +2 -0
  80. data/lib/grape/middleware/helpers.rb +12 -0
  81. data/lib/grape/middleware/stack.rb +16 -6
  82. data/lib/grape/middleware/versioner/accept_version_header.rb +5 -5
  83. data/lib/grape/middleware/versioner/header.rb +13 -9
  84. data/lib/grape/middleware/versioner/param.rb +4 -1
  85. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +5 -1
  86. data/lib/grape/middleware/versioner/path.rb +5 -1
  87. data/lib/grape/middleware/versioner.rb +2 -0
  88. data/lib/grape/namespace.rb +14 -2
  89. data/lib/grape/parser/json.rb +3 -1
  90. data/lib/grape/parser/xml.rb +3 -1
  91. data/lib/grape/parser.rb +4 -2
  92. data/lib/grape/path.rb +16 -3
  93. data/lib/grape/presenters/presenter.rb +2 -0
  94. data/lib/grape/request.rb +21 -9
  95. data/lib/grape/router/attribute_translator.rb +41 -8
  96. data/lib/grape/router/pattern.rb +21 -17
  97. data/lib/grape/router/route.rb +15 -29
  98. data/lib/grape/router.rb +36 -29
  99. data/lib/grape/{serve_file → serve_stream}/file_body.rb +3 -1
  100. data/lib/grape/{serve_file → serve_stream}/sendfile_response.rb +3 -1
  101. data/lib/grape/{serve_file/file_response.rb → serve_stream/stream_response.rb} +10 -8
  102. data/lib/grape/types/invalid_value.rb +8 -0
  103. data/lib/grape/util/base_inheritable.rb +43 -0
  104. data/lib/grape/util/cache.rb +20 -0
  105. data/lib/grape/util/endpoint_configuration.rb +8 -0
  106. data/lib/grape/util/env.rb +19 -17
  107. data/lib/grape/util/inheritable_setting.rb +3 -3
  108. data/lib/grape/util/inheritable_values.rb +7 -25
  109. data/lib/grape/util/json.rb +4 -0
  110. data/lib/grape/util/lazy_block.rb +27 -0
  111. data/lib/grape/util/lazy_object.rb +43 -0
  112. data/lib/grape/util/lazy_value.rb +99 -0
  113. data/lib/grape/util/registrable.rb +2 -0
  114. data/lib/grape/util/reverse_stackable_values.rb +10 -35
  115. data/lib/grape/util/stackable_values.rb +21 -34
  116. data/lib/grape/util/strict_hash_configuration.rb +3 -1
  117. data/lib/grape/util/xml.rb +2 -0
  118. data/lib/grape/validations/attributes_doc.rb +58 -0
  119. data/lib/grape/validations/attributes_iterator.rb +16 -6
  120. data/lib/grape/validations/multiple_attributes_iterator.rb +13 -0
  121. data/lib/grape/validations/params_scope.rb +174 -94
  122. data/lib/grape/validations/single_attribute_iterator.rb +24 -0
  123. data/lib/grape/validations/types/array_coercer.rb +63 -0
  124. data/lib/grape/validations/types/build_coercer.rb +47 -49
  125. data/lib/grape/validations/types/custom_type_coercer.rb +30 -51
  126. data/lib/grape/validations/types/custom_type_collection_coercer.rb +10 -25
  127. data/lib/grape/validations/types/dry_type_coercer.rb +72 -0
  128. data/lib/grape/validations/types/file.rb +22 -18
  129. data/lib/grape/validations/types/invalid_value.rb +17 -0
  130. data/lib/grape/validations/types/json.rb +47 -39
  131. data/lib/grape/validations/types/multiple_type_coercer.rb +14 -33
  132. data/lib/grape/validations/types/primitive_coercer.rb +75 -0
  133. data/lib/grape/validations/types/set_coercer.rb +38 -0
  134. data/lib/grape/validations/types/variant_collection_coercer.rb +5 -13
  135. data/lib/grape/validations/types.rb +106 -63
  136. data/lib/grape/validations/validator_factory.rb +8 -11
  137. data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
  138. data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
  139. data/lib/grape/validations/validators/as_validator.rb +14 -0
  140. data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
  141. data/lib/grape/validations/validators/base.rb +84 -68
  142. data/lib/grape/validations/validators/coerce_validator.rb +75 -0
  143. data/lib/grape/validations/validators/default_validator.rb +51 -0
  144. data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
  145. data/lib/grape/validations/validators/except_values_validator.rb +24 -0
  146. data/lib/grape/validations/validators/multiple_params_base.rb +27 -16
  147. data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
  148. data/lib/grape/validations/validators/presence_validator.rb +15 -0
  149. data/lib/grape/validations/validators/regexp_validator.rb +16 -0
  150. data/lib/grape/validations/validators/same_as_validator.rb +29 -0
  151. data/lib/grape/validations/validators/values_validator.rb +88 -0
  152. data/lib/grape/validations.rb +18 -6
  153. data/lib/grape/version.rb +3 -1
  154. data/lib/grape.rb +175 -94
  155. data/spec/grape/api/custom_validations_spec.rb +117 -44
  156. data/spec/grape/api/deeply_included_options_spec.rb +4 -4
  157. data/spec/grape/api/defines_boolean_in_params_spec.rb +38 -0
  158. data/spec/grape/api/documentation_spec.rb +59 -0
  159. data/spec/grape/api/inherited_helpers_spec.rb +1 -1
  160. data/spec/grape/api/instance_spec.rb +103 -0
  161. data/spec/grape/api/invalid_format_spec.rb +3 -1
  162. data/spec/grape/api/namespace_parameters_in_route_spec.rb +1 -1
  163. data/spec/grape/api/nested_helpers_spec.rb +1 -1
  164. data/spec/grape/api/optional_parameters_in_route_spec.rb +1 -1
  165. data/spec/grape/api/parameters_modification_spec.rb +2 -2
  166. data/spec/grape/api/patch_method_helpers_spec.rb +1 -1
  167. data/spec/grape/api/recognize_path_spec.rb +2 -2
  168. data/spec/grape/api/required_parameters_in_route_spec.rb +1 -1
  169. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +1 -1
  170. data/spec/grape/api/routes_with_requirements_spec.rb +59 -0
  171. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +10 -16
  172. data/spec/grape/api/shared_helpers_spec.rb +1 -1
  173. data/spec/grape/api_remount_spec.rb +473 -0
  174. data/spec/grape/api_spec.rb +995 -231
  175. data/spec/grape/config_spec.rb +17 -0
  176. data/spec/grape/dsl/callbacks_spec.rb +3 -2
  177. data/spec/grape/dsl/desc_spec.rb +43 -17
  178. data/spec/grape/dsl/headers_spec.rb +40 -10
  179. data/spec/grape/dsl/helpers_spec.rb +6 -5
  180. data/spec/grape/dsl/inside_route_spec.rb +189 -38
  181. data/spec/grape/dsl/logger_spec.rb +17 -19
  182. data/spec/grape/dsl/middleware_spec.rb +11 -2
  183. data/spec/grape/dsl/parameters_spec.rb +3 -1
  184. data/spec/grape/dsl/request_response_spec.rb +8 -7
  185. data/spec/grape/dsl/routing_spec.rb +22 -9
  186. data/spec/grape/dsl/settings_spec.rb +1 -1
  187. data/spec/grape/dsl/validations_spec.rb +1 -16
  188. data/spec/grape/endpoint/declared_spec.rb +846 -0
  189. data/spec/grape/endpoint_spec.rb +136 -577
  190. data/spec/grape/entity_spec.rb +31 -24
  191. data/spec/grape/exceptions/base_spec.rb +81 -0
  192. data/spec/grape/exceptions/body_parse_errors_spec.rb +4 -1
  193. data/spec/grape/exceptions/invalid_accept_header_spec.rb +65 -23
  194. data/spec/grape/exceptions/invalid_formatter_spec.rb +1 -1
  195. data/spec/grape/exceptions/invalid_response_spec.rb +11 -0
  196. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +2 -2
  197. data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
  198. data/spec/grape/exceptions/missing_mime_type_spec.rb +1 -1
  199. data/spec/grape/exceptions/missing_option_spec.rb +2 -2
  200. data/spec/grape/exceptions/unknown_options_spec.rb +1 -1
  201. data/spec/grape/exceptions/unknown_validator_spec.rb +1 -1
  202. data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
  203. data/spec/grape/exceptions/validation_errors_spec.rb +21 -15
  204. data/spec/grape/exceptions/validation_spec.rb +6 -4
  205. data/spec/grape/extensions/param_builders/hash_spec.rb +8 -8
  206. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +9 -9
  207. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +9 -9
  208. data/spec/grape/integration/global_namespace_function_spec.rb +2 -2
  209. data/spec/grape/integration/rack_sendfile_spec.rb +14 -10
  210. data/spec/grape/integration/rack_spec.rb +25 -8
  211. data/spec/grape/loading_spec.rb +9 -9
  212. data/spec/grape/middleware/auth/base_spec.rb +2 -1
  213. data/spec/grape/middleware/auth/dsl_spec.rb +19 -10
  214. data/spec/grape/middleware/auth/strategies_spec.rb +62 -22
  215. data/spec/grape/middleware/base_spec.rb +36 -17
  216. data/spec/grape/middleware/error_spec.rb +11 -4
  217. data/spec/grape/middleware/exception_spec.rb +112 -162
  218. data/spec/grape/middleware/formatter_spec.rb +65 -29
  219. data/spec/grape/middleware/globals_spec.rb +8 -5
  220. data/spec/grape/middleware/stack_spec.rb +25 -13
  221. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +3 -2
  222. data/spec/grape/middleware/versioner/header_spec.rb +37 -14
  223. data/spec/grape/middleware/versioner/param_spec.rb +8 -2
  224. data/spec/grape/middleware/versioner/path_spec.rb +6 -2
  225. data/spec/grape/middleware/versioner_spec.rb +2 -2
  226. data/spec/grape/named_api_spec.rb +19 -0
  227. data/spec/grape/parser_spec.rb +10 -6
  228. data/spec/grape/path_spec.rb +53 -53
  229. data/spec/grape/presenters/presenter_spec.rb +8 -7
  230. data/spec/grape/request_spec.rb +29 -3
  231. data/spec/grape/util/inheritable_setting_spec.rb +9 -8
  232. data/spec/grape/util/inheritable_values_spec.rb +5 -3
  233. data/spec/grape/util/reverse_stackable_values_spec.rb +5 -2
  234. data/spec/grape/util/stackable_values_spec.rb +10 -7
  235. data/spec/grape/util/strict_hash_configuration_spec.rb +2 -1
  236. data/spec/grape/validations/attributes_doc_spec.rb +153 -0
  237. data/spec/grape/validations/instance_behaivour_spec.rb +13 -14
  238. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +40 -0
  239. data/spec/grape/validations/params_scope_spec.rb +568 -99
  240. data/spec/grape/validations/single_attribute_iterator_spec.rb +57 -0
  241. data/spec/grape/validations/types/array_coercer_spec.rb +33 -0
  242. data/spec/grape/validations/types/primitive_coercer_spec.rb +150 -0
  243. data/spec/grape/validations/types/set_coercer_spec.rb +32 -0
  244. data/spec/grape/validations/types_spec.rb +44 -45
  245. data/spec/grape/validations/validators/all_or_none_spec.rb +134 -32
  246. data/spec/grape/validations/validators/allow_blank_spec.rb +137 -141
  247. data/spec/grape/validations/validators/at_least_one_of_spec.rb +169 -31
  248. data/spec/grape/validations/validators/coerce_spec.rb +491 -151
  249. data/spec/grape/validations/validators/default_spec.rb +242 -78
  250. data/spec/grape/validations/validators/exactly_one_of_spec.rb +198 -40
  251. data/spec/grape/validations/validators/except_values_spec.rb +6 -5
  252. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +181 -30
  253. data/spec/grape/validations/validators/presence_spec.rb +45 -2
  254. data/spec/grape/validations/validators/regexp_spec.rb +27 -33
  255. data/spec/grape/validations/validators/same_as_spec.rb +57 -0
  256. data/spec/grape/validations/validators/values_spec.rb +227 -180
  257. data/spec/grape/validations_spec.rb +502 -72
  258. data/spec/integration/eager_load/eager_load_spec.rb +15 -0
  259. data/spec/integration/multi_json/json_spec.rb +2 -2
  260. data/spec/integration/multi_xml/xml_spec.rb +2 -2
  261. data/spec/shared/versioning_examples.rb +34 -29
  262. data/spec/spec_helper.rb +31 -5
  263. data/spec/support/basic_auth_encode_helpers.rb +3 -1
  264. data/spec/support/chunks.rb +14 -0
  265. data/spec/support/content_type_helpers.rb +2 -0
  266. data/spec/support/endpoint_faker.rb +2 -0
  267. data/spec/support/file_streamer.rb +2 -0
  268. data/spec/support/integer_helpers.rb +2 -0
  269. data/spec/support/versioned_helpers.rb +8 -8
  270. metadata +111 -61
  271. data/Appraisals +0 -32
  272. data/Dangerfile +0 -2
  273. data/Gemfile +0 -33
  274. data/Gemfile.lock +0 -231
  275. data/Guardfile +0 -10
  276. data/RELEASING.md +0 -111
  277. data/Rakefile +0 -25
  278. data/benchmark/simple.rb +0 -27
  279. data/benchmark/simple_with_type_coercer.rb +0 -22
  280. data/gemfiles/multi_json.gemfile +0 -35
  281. data/gemfiles/multi_xml.gemfile +0 -35
  282. data/gemfiles/rack_1.5.2.gemfile +0 -35
  283. data/gemfiles/rack_edge.gemfile +0 -35
  284. data/gemfiles/rails_3.gemfile +0 -36
  285. data/gemfiles/rails_4.gemfile +0 -35
  286. data/gemfiles/rails_5.gemfile +0 -35
  287. data/gemfiles/rails_edge.gemfile +0 -35
  288. data/lib/grape/extensions/deep_hash_with_indifferent_access.rb +0 -18
  289. data/lib/grape/util/content_types.rb +0 -26
  290. data/lib/grape/validations/types/virtus_collection_patch.rb +0 -16
  291. data/lib/grape/validations/validators/all_or_none.rb +0 -20
  292. data/lib/grape/validations/validators/allow_blank.rb +0 -16
  293. data/lib/grape/validations/validators/as.rb +0 -15
  294. data/lib/grape/validations/validators/at_least_one_of.rb +0 -20
  295. data/lib/grape/validations/validators/coerce.rb +0 -74
  296. data/lib/grape/validations/validators/default.rb +0 -48
  297. data/lib/grape/validations/validators/exactly_one_of.rb +0 -29
  298. data/lib/grape/validations/validators/except_values.rb +0 -20
  299. data/lib/grape/validations/validators/mutual_exclusion.rb +0 -25
  300. data/lib/grape/validations/validators/presence.rb +0 -10
  301. data/lib/grape/validations/validators/regexp.rb +0 -11
  302. data/lib/grape/validations/validators/values.rb +0 -71
  303. data/pkg/grape-0.17.0.gem +0 -0
  304. data/pkg/grape-0.19.0.gem +0 -0
  305. data/spec/grape/dsl/configuration_spec.rb +0 -14
  306. data/spec/grape/validations/attributes_iterator_spec.rb +0 -4
@@ -1,4 +1,4 @@
1
- require 'active_support/concern'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Grape
4
4
  module DSL
@@ -16,21 +16,28 @@ module Grape
16
16
  # to inject.
17
17
  def use(middleware_class, *args, &block)
18
18
  arr = [:use, middleware_class, *args]
19
- arr << block if block_given?
19
+ arr << block if block
20
+
21
+ namespace_stackable(:middleware, arr)
22
+ end
23
+
24
+ def insert(*args, &block)
25
+ arr = [:insert, *args]
26
+ arr << block if block
20
27
 
21
28
  namespace_stackable(:middleware, arr)
22
29
  end
23
30
 
24
31
  def insert_before(*args, &block)
25
32
  arr = [:insert_before, *args]
26
- arr << block if block_given?
33
+ arr << block if block
27
34
 
28
35
  namespace_stackable(:middleware, arr)
29
36
  end
30
37
 
31
38
  def insert_after(*args, &block)
32
39
  arr = [:insert_after, *args]
33
- arr << block if block_given?
40
+ arr << block if block
34
41
 
35
42
  namespace_stackable(:middleware, arr)
36
43
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/concern'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Grape
4
4
  module DSL
@@ -62,7 +62,12 @@ module Grape
62
62
  params_block = named_params.fetch(name) do
63
63
  raise "Params :#{name} not found!"
64
64
  end
65
- instance_exec(options, &params_block)
65
+
66
+ if options.empty?
67
+ instance_exec(options, &params_block)
68
+ else
69
+ instance_exec(**options, &params_block)
70
+ end
66
71
  end
67
72
  end
68
73
  alias use_scope use
@@ -70,7 +75,7 @@ module Grape
70
75
 
71
76
  # Require one or more parameters for the current endpoint.
72
77
  #
73
- # @param attrs list of parameter names, or, if :using is
78
+ # @param attrs list of parameters names, or, if :using is
74
79
  # passed as an option, which keys to include (:all or :none) from
75
80
  # the :using hash. The last key can be a hash, which specifies
76
81
  # options for the parameters
@@ -125,13 +130,13 @@ module Grape
125
130
 
126
131
  opts = attrs.extract_options!.clone
127
132
  opts[:presence] = { value: true, message: opts[:message] }
128
- opts = @group.merge(opts) if @group
133
+ opts = @group.merge(opts) if instance_variable_defined?(:@group) && @group
129
134
 
130
135
  if opts[:using]
131
136
  require_required_and_optional_fields(attrs.first, opts)
132
137
  else
133
138
  validate_attributes(attrs, opts, &block)
134
- block_given? ? new_scope(orig_attrs, &block) : push_declared_params(attrs, opts.slice(:as))
139
+ block ? new_scope(orig_attrs, &block) : push_declared_params(attrs, **opts.slice(:as))
135
140
  end
136
141
  end
137
142
 
@@ -144,12 +149,12 @@ module Grape
144
149
 
145
150
  opts = attrs.extract_options!.clone
146
151
  type = opts[:type]
147
- opts = @group.merge(opts) if @group
152
+ opts = @group.merge(opts) if instance_variable_defined?(:@group) && @group
148
153
 
149
154
  # check type for optional parameter group
150
- if attrs && block_given?
151
- raise Grape::Exceptions::MissingGroupTypeError.new if type.nil?
152
- raise Grape::Exceptions::UnsupportedGroupTypeError.new unless Grape::Validations::Types.group?(type)
155
+ if attrs && block
156
+ raise Grape::Exceptions::MissingGroupType if type.nil?
157
+ raise Grape::Exceptions::UnsupportedGroupType unless Grape::Validations::Types.group?(type)
153
158
  end
154
159
 
155
160
  if opts[:using]
@@ -157,7 +162,7 @@ module Grape
157
162
  else
158
163
  validate_attributes(attrs, opts, &block)
159
164
 
160
- block_given? ? new_scope(orig_attrs, true, &block) : push_declared_params(attrs, opts.slice(:as))
165
+ block ? new_scope(orig_attrs, true, &block) : push_declared_params(attrs, **opts.slice(:as))
161
166
  end
162
167
  end
163
168
 
@@ -211,22 +216,31 @@ module Grape
211
216
  # block yet.
212
217
  # @return [Boolean] whether the parameter has been defined
213
218
  def declared_param?(param)
214
- # @declared_params also includes hashes of options and such, but those
215
- # won't be flattened out.
216
- @declared_params.flatten.any? do |declared_param|
217
- first_hash_key_or_param(declared_param) == param
219
+ if lateral?
220
+ # Elements of @declared_params of lateral scope are pushed in @parent. So check them in @parent.
221
+ @parent.declared_param?(param)
222
+ else
223
+ # @declared_params also includes hashes of options and such, but those
224
+ # won't be flattened out.
225
+ @declared_params.flatten.any? do |declared_param_attr|
226
+ first_hash_key_or_param(declared_param_attr.key) == param
227
+ end
218
228
  end
219
229
  end
220
230
 
221
231
  alias group requires
222
232
 
223
- def map_params(params, element)
233
+ class EmptyOptionalValue; end
234
+
235
+ def map_params(params, element, is_array = false)
224
236
  if params.is_a?(Array)
225
237
  params.map do |el|
226
- map_params(el, element)
238
+ map_params(el, element, true)
227
239
  end
228
240
  elsif params.is_a?(Hash)
229
- params[element] || {}
241
+ params[element] || (@optional && is_array ? EmptyOptionalValue : {})
242
+ elsif params == EmptyOptionalValue
243
+ EmptyOptionalValue
230
244
  else
231
245
  {}
232
246
  end
@@ -236,8 +250,8 @@ module Grape
236
250
  # @return hash of parameters relevant for the current scope
237
251
  # @api private
238
252
  def params(params)
239
- params = @parent.params(params) if @parent
240
- params = map_params(params, @element) if @element
253
+ params = @parent.params(params) if instance_variable_defined?(:@parent) && @parent
254
+ params = map_params(params, @element) if instance_variable_defined?(:@element) && @element
241
255
  params
242
256
  end
243
257
 
@@ -1,4 +1,4 @@
1
- require 'active_support/concern'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Grape
4
4
  module DSL
@@ -20,10 +20,11 @@ module Grape
20
20
  if new_format
21
21
  namespace_inheritable(:format, new_format.to_sym)
22
22
  # define the default error formatters
23
- namespace_inheritable(:default_error_formatter, Grape::ErrorFormatter.formatter_for(new_format, {}))
23
+ namespace_inheritable(:default_error_formatter, Grape::ErrorFormatter.formatter_for(new_format, **{}))
24
24
  # define a single mime type
25
25
  mime_type = content_types[new_format.to_sym]
26
26
  raise Grape::Exceptions::MissingMimeType.new(new_format) unless mime_type
27
+
27
28
  namespace_stackable(:content_types, new_format.to_sym => mime_type)
28
29
  else
29
30
  namespace_inheritable(:format)
@@ -43,7 +44,7 @@ module Grape
43
44
  # Specify a default error formatter.
44
45
  def default_error_formatter(new_formatter_name = nil)
45
46
  if new_formatter_name
46
- new_formatter = Grape::ErrorFormatter.formatter_for(new_formatter_name, {})
47
+ new_formatter = Grape::ErrorFormatter.formatter_for(new_formatter_name, **{})
47
48
  namespace_inheritable(:default_error_formatter, new_formatter)
48
49
  else
49
50
  namespace_inheritable(:default_error_formatter)
@@ -100,14 +101,13 @@ module Grape
100
101
  def rescue_from(*args, &block)
101
102
  if args.last.is_a?(Proc)
102
103
  handler = args.pop
103
- elsif block_given?
104
+ elsif block
104
105
  handler = block
105
106
  end
106
107
 
107
108
  options = args.extract_options!
108
- if block_given? && options.key?(:with)
109
- raise ArgumentError, 'both :with option and block cannot be passed'
110
- end
109
+ raise ArgumentError, 'both :with option and block cannot be passed' if block && options.key?(:with)
110
+
111
111
  handler ||= extract_with(options)
112
112
 
113
113
  if args.include?(:all)
@@ -125,7 +125,7 @@ module Grape
125
125
  :base_only_rescue_handlers
126
126
  end
127
127
 
128
- namespace_reverse_stackable handler_type, Hash[args.map { |arg| [arg, handler] }]
128
+ namespace_reverse_stackable(handler_type, args.to_h { |arg| [arg, handler] })
129
129
  end
130
130
 
131
131
  namespace_stackable(:rescue_options, options)
@@ -152,7 +152,8 @@ module Grape
152
152
  # @param model_class [Class] The model class that will be represented.
153
153
  # @option options [Class] :with The entity class that will represent the model.
154
154
  def represent(model_class, options)
155
- raise Grape::Exceptions::InvalidWithOptionForRepresent.new unless options[:with] && options[:with].is_a?(Class)
155
+ raise Grape::Exceptions::InvalidWithOptionForRepresent.new unless options[:with].is_a?(Class)
156
+
156
157
  namespace_stackable(:representations, model_class => options[:with])
157
158
  end
158
159
 
@@ -160,9 +161,11 @@ module Grape
160
161
 
161
162
  def extract_with(options)
162
163
  return unless options.key?(:with)
164
+
163
165
  with_option = options.delete(:with)
164
166
  return with_option if with_option.instance_of?(Proc)
165
167
  return with_option.to_sym if with_option.instance_of?(Symbol) || with_option.instance_of?(String)
168
+
166
169
  raise ArgumentError, "with: #{with_option.class}, expected Symbol, String or Proc"
167
170
  end
168
171
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/concern'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Grape
4
4
  module DSL
@@ -36,7 +36,7 @@ module Grape
36
36
 
37
37
  @versions = versions | requested_versions
38
38
 
39
- if block_given?
39
+ if block
40
40
  within_namespace do
41
41
  namespace_inheritable(:version, requested_versions)
42
42
  namespace_inheritable(:version_options, options)
@@ -49,7 +49,7 @@ module Grape
49
49
  end
50
50
  end
51
51
 
52
- @versions.last unless @versions.nil?
52
+ @versions.last if instance_variable_defined?(:@versions) && @versions
53
53
  end
54
54
 
55
55
  # Define a root URL prefix for your entire API.
@@ -77,9 +77,18 @@ module Grape
77
77
  namespace_inheritable(:do_not_route_options, true)
78
78
  end
79
79
 
80
- def mount(mounts)
80
+ def do_not_document!
81
+ namespace_inheritable(:do_not_document, true)
82
+ end
83
+
84
+ def mount(mounts, *opts)
81
85
  mounts = { mounts => '/' } unless mounts.respond_to?(:each_pair)
82
86
  mounts.each_pair do |app, path|
87
+ if app.respond_to?(:mount_instance)
88
+ opts_with = opts.any? ? opts.shift[:with] : {}
89
+ mount({ app.mount_instance(configuration: opts_with) => path })
90
+ next
91
+ end
83
92
  in_setting = inheritable_setting
84
93
 
85
94
  if app.respond_to?(:inheritable_setting, true)
@@ -136,16 +145,16 @@ module Grape
136
145
  reset_validations!
137
146
  end
138
147
 
139
- %w[get post put head delete options patch].each do |meth|
140
- define_method meth do |*args, &block|
148
+ Grape::Http::Headers::SUPPORTED_METHODS.each do |supported_method|
149
+ define_method supported_method.downcase do |*args, &block|
141
150
  options = args.extract_options!
142
151
  paths = args.first || ['/']
143
- route(meth.upcase, paths, options, &block)
152
+ route(supported_method, paths, options, &block)
144
153
  end
145
154
  end
146
155
 
147
156
  # Declare a "namespace", which prefixes all subordinate routes with its
148
- # name. Any endpoints within a namespace, or group, resource, segment,
157
+ # name. Any endpoints within a namespace, group, resource or segment,
149
158
  # etc., will share their parent context as well as any configuration
150
159
  # done in the namespace context.
151
160
  #
@@ -157,14 +166,14 @@ module Grape
157
166
  # end
158
167
  # end
159
168
  def namespace(space = nil, options = {}, &block)
160
- if space || block_given?
169
+ @namespace_description = nil unless instance_variable_defined?(:@namespace_description) && @namespace_description
170
+
171
+ if space || block
161
172
  within_namespace do
162
173
  previous_namespace_description = @namespace_description
163
174
  @namespace_description = (@namespace_description || {}).deep_merge(namespace_setting(:description) || {})
164
175
  nest(block) do
165
- if space
166
- namespace_stackable(:namespace, Namespace.new(space, options))
167
- end
176
+ namespace_stackable(:namespace, Namespace.new(space, **options)) if space
168
177
  end
169
178
  @namespace_description = previous_namespace_description
170
179
  end
@@ -193,7 +202,7 @@ module Grape
193
202
  @endpoints = []
194
203
  end
195
204
 
196
- # Thie method allows you to quickly define a parameter route segment
205
+ # This method allows you to quickly define a parameter route segment
197
206
  # in your API.
198
207
  #
199
208
  # @param param [Symbol] The name of the parameter you wish to declare.
@@ -1,4 +1,4 @@
1
- require 'active_support/concern'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Grape
4
4
  module DSL
@@ -101,12 +101,14 @@ module Grape
101
101
  def namespace_stackable_with_hash(key)
102
102
  settings = get_or_set :namespace_stackable, key, nil
103
103
  return if settings.blank?
104
+
104
105
  settings.each_with_object({}) { |value, result| result.deep_merge!(value) }
105
106
  end
106
107
 
107
108
  def namespace_reverse_stackable_with_hash(key)
108
109
  settings = get_or_set :namespace_reverse_stackable, key, nil
109
110
  return if settings.blank?
111
+
110
112
  result = {}
111
113
  settings.each do |setting|
112
114
  setting.each do |field, value|
@@ -152,10 +154,10 @@ module Grape
152
154
 
153
155
  # Execute the block within a context where our inheritable settings are forked
154
156
  # to a new copy (see #namespace_start).
155
- def within_namespace(&_block)
157
+ def within_namespace(&block)
156
158
  namespace_start
157
159
 
158
- result = yield if block_given?
160
+ result = yield if block
159
161
 
160
162
  namespace_end
161
163
  reset_validations!
@@ -169,9 +171,11 @@ module Grape
169
171
  # the superclass's :inheritable_setting.
170
172
  def build_top_level_setting
171
173
  Grape::Util::InheritableSetting.new.tap do |setting|
172
- if defined?(superclass) && superclass.respond_to?(:inheritable_setting) && superclass != Grape::API
173
- setting.inherit_from superclass.inheritable_setting
174
- end
174
+ # Doesn't try to inherit settings from +Grape::API::Instance+ which also responds to
175
+ # +inheritable_setting+, however, it doesn't contain any user-defined settings.
176
+ # Otherwise, it would lead to an extra instance of +Grape::Util::InheritableSetting+
177
+ # in the chain for every endpoint.
178
+ setting.inherit_from superclass.inheritable_setting if defined?(superclass) && superclass.respond_to?(:inheritable_setting) && superclass != Grape::API::Instance
175
179
  end
176
180
  end
177
181
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/concern'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Grape
4
4
  module DSL
@@ -8,12 +8,28 @@ module Grape
8
8
  include Grape::DSL::Configuration
9
9
 
10
10
  module ClassMethods
11
- # Clears all defined parameters and validations.
11
+ # Clears all defined parameters and validations. The main purpose of it is to clean up
12
+ # settings, so next endpoint won't interfere with previous one.
13
+ #
14
+ # params do
15
+ # # params for the endpoint below this block
16
+ # end
17
+ # post '/current' do
18
+ # # whatever
19
+ # end
20
+ #
21
+ # # somewhere between them the reset_validations! method gets called
22
+ #
23
+ # params do
24
+ # # params for the endpoint below this block
25
+ # end
26
+ # post '/next' do
27
+ # # whatever
28
+ # end
12
29
  def reset_validations!
13
30
  unset_namespace_stackable :declared_params
14
31
  unset_namespace_stackable :validations
15
32
  unset_namespace_stackable :params
16
- unset_description_field :params
17
33
  end
18
34
 
19
35
  # Opens a root-level ParamsScope, defining parameter coercions and
@@ -22,17 +38,6 @@ module Grape
22
38
  def params(&block)
23
39
  Grape::Validations::ParamsScope.new(api: self, type: Hash, &block)
24
40
  end
25
-
26
- def document_attribute(names, opts)
27
- setting = description_field(:params)
28
- setting ||= description_field(:params, {})
29
- Array(names).each do |name|
30
- setting[name[:full_name].to_s] ||= {}
31
- setting[name[:full_name].to_s].merge!(opts)
32
-
33
- namespace_stackable(:params, name[:full_name].to_s => opts)
34
- end
35
- end
36
41
  end
37
42
  end
38
43
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ Grape.eager_load!
4
+ Grape::Http.eager_load!
5
+ Grape::Exceptions.eager_load!
6
+ Grape::Extensions.eager_load!
7
+ Grape::Extensions::ActiveSupport.eager_load!
8
+ Grape::Extensions::Hashie.eager_load!
9
+ Grape::Middleware.eager_load!
10
+ Grape::Middleware::Auth.eager_load!
11
+ Grape::Middleware::Versioner.eager_load!
12
+ Grape::Util.eager_load!
13
+ Grape::ErrorFormatter.eager_load!
14
+ Grape::Formatter.eager_load!
15
+ Grape::Parser.eager_load!
16
+ Grape::DSL.eager_load!
17
+ Grape::API.eager_load!
18
+ Grape::Presenters.eager_load!
19
+ Grape::ServeStream.eager_load!
20
+ Rack::Head # AutoLoads the Rack::Head