grape 1.5.3 → 1.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +67 -0
- data/CONTRIBUTING.md +2 -1
- data/README.md +150 -21
- data/UPGRADING.md +61 -4
- data/grape.gemspec +5 -5
- data/lib/grape/api/instance.rb +14 -18
- data/lib/grape/api.rb +17 -12
- data/lib/grape/cookies.rb +2 -0
- data/lib/grape/dry_types.rb +12 -0
- data/lib/grape/dsl/api.rb +0 -2
- data/lib/grape/dsl/callbacks.rb +0 -2
- data/lib/grape/dsl/configuration.rb +0 -2
- data/lib/grape/dsl/desc.rb +2 -19
- data/lib/grape/dsl/headers.rb +5 -2
- data/lib/grape/dsl/helpers.rb +7 -7
- data/lib/grape/dsl/inside_route.rb +43 -30
- data/lib/grape/dsl/middleware.rb +4 -6
- data/lib/grape/dsl/parameters.rb +8 -10
- data/lib/grape/dsl/request_response.rb +9 -8
- data/lib/grape/dsl/routing.rb +6 -4
- data/lib/grape/dsl/settings.rb +5 -7
- data/lib/grape/dsl/validations.rb +0 -15
- data/lib/grape/endpoint.rb +20 -35
- data/lib/grape/error_formatter/json.rb +9 -7
- data/lib/grape/error_formatter/xml.rb +2 -6
- data/lib/grape/exceptions/base.rb +2 -2
- data/lib/grape/exceptions/missing_group_type.rb +8 -1
- data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
- data/lib/grape/exceptions/unsupported_group_type.rb +8 -1
- data/lib/grape/exceptions/validation.rb +1 -6
- data/lib/grape/formatter/json.rb +1 -0
- data/lib/grape/formatter/serializable_hash.rb +2 -1
- data/lib/grape/formatter/xml.rb +1 -0
- data/lib/grape/locale/en.yml +9 -8
- data/lib/grape/middleware/auth/dsl.rb +7 -2
- data/lib/grape/middleware/base.rb +3 -1
- data/lib/grape/middleware/error.rb +2 -2
- data/lib/grape/middleware/formatter.rb +4 -4
- data/lib/grape/middleware/stack.rb +2 -2
- data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
- data/lib/grape/middleware/versioner/header.rb +6 -4
- data/lib/grape/middleware/versioner/param.rb +1 -0
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
- data/lib/grape/middleware/versioner/path.rb +2 -0
- data/lib/grape/path.rb +1 -0
- data/lib/grape/request.rb +3 -0
- data/lib/grape/router/pattern.rb +1 -1
- data/lib/grape/router/route.rb +2 -2
- data/lib/grape/router.rb +6 -0
- data/lib/grape/util/inheritable_setting.rb +1 -3
- data/lib/grape/util/json.rb +2 -0
- data/lib/grape/util/lazy_value.rb +3 -2
- data/lib/grape/util/strict_hash_configuration.rb +1 -1
- data/lib/grape/validations/attributes_doc.rb +58 -0
- data/lib/grape/validations/params_scope.rb +137 -78
- data/lib/grape/validations/types/array_coercer.rb +0 -2
- data/lib/grape/validations/types/custom_type_coercer.rb +1 -0
- data/lib/grape/validations/types/dry_type_coercer.rb +4 -8
- data/lib/grape/validations/types/json.rb +2 -1
- data/lib/grape/validations/types/primitive_coercer.rb +16 -8
- data/lib/grape/validations/types/set_coercer.rb +0 -2
- data/lib/grape/validations/types.rb +98 -30
- data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
- data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
- data/lib/grape/validations/validators/as_validator.rb +14 -0
- data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
- data/lib/grape/validations/validators/base.rb +82 -70
- data/lib/grape/validations/validators/coerce_validator.rb +75 -0
- data/lib/grape/validations/validators/default_validator.rb +51 -0
- data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
- data/lib/grape/validations/validators/except_values_validator.rb +24 -0
- data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
- data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
- data/lib/grape/validations/validators/presence_validator.rb +15 -0
- data/lib/grape/validations/validators/regexp_validator.rb +16 -0
- data/lib/grape/validations/validators/same_as_validator.rb +29 -0
- data/lib/grape/validations/validators/values_validator.rb +88 -0
- data/lib/grape/validations.rb +16 -6
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +69 -29
- data/spec/grape/api/custom_validations_spec.rb +116 -45
- data/spec/grape/api/deeply_included_options_spec.rb +3 -5
- data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -3
- data/spec/grape/api/documentation_spec.rb +59 -0
- data/spec/grape/api/inherited_helpers_spec.rb +0 -2
- data/spec/grape/api/instance_spec.rb +0 -1
- data/spec/grape/api/invalid_format_spec.rb +2 -2
- data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/nested_helpers_spec.rb +0 -2
- data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/parameters_modification_spec.rb +0 -2
- data/spec/grape/api/patch_method_helpers_spec.rb +0 -2
- data/spec/grape/api/recognize_path_spec.rb +1 -3
- data/spec/grape/api/required_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -2
- data/spec/grape/api/routes_with_requirements_spec.rb +8 -10
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -17
- data/spec/grape/api/shared_helpers_spec.rb +0 -2
- data/spec/grape/api_remount_spec.rb +16 -16
- data/spec/grape/api_spec.rb +457 -231
- data/spec/grape/config_spec.rb +0 -2
- data/spec/grape/dsl/callbacks_spec.rb +2 -3
- data/spec/grape/dsl/configuration_spec.rb +0 -2
- data/spec/grape/dsl/desc_spec.rb +0 -2
- data/spec/grape/dsl/headers_spec.rb +39 -11
- data/spec/grape/dsl/helpers_spec.rb +3 -4
- data/spec/grape/dsl/inside_route_spec.rb +16 -16
- data/spec/grape/dsl/logger_spec.rb +15 -19
- data/spec/grape/dsl/middleware_spec.rb +2 -3
- data/spec/grape/dsl/parameters_spec.rb +2 -2
- data/spec/grape/dsl/request_response_spec.rb +7 -8
- data/spec/grape/dsl/routing_spec.rb +11 -10
- data/spec/grape/dsl/settings_spec.rb +0 -2
- data/spec/grape/dsl/validations_spec.rb +0 -17
- data/spec/grape/endpoint/declared_spec.rb +261 -16
- data/spec/grape/endpoint_spec.rb +86 -58
- data/spec/grape/entity_spec.rb +22 -23
- data/spec/grape/exceptions/base_spec.rb +16 -2
- data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -2
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +61 -24
- data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_response_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -3
- data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
- data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -2
- data/spec/grape/exceptions/missing_option_spec.rb +1 -3
- data/spec/grape/exceptions/unknown_options_spec.rb +0 -2
- data/spec/grape/exceptions/unknown_validator_spec.rb +0 -2
- data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
- data/spec/grape/exceptions/validation_errors_spec.rb +13 -11
- data/spec/grape/exceptions/validation_spec.rb +5 -5
- data/spec/grape/extensions/param_builders/hash_spec.rb +7 -9
- data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -10
- data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -10
- data/spec/grape/integration/global_namespace_function_spec.rb +0 -2
- data/spec/grape/integration/rack_sendfile_spec.rb +1 -3
- data/spec/grape/integration/rack_spec.rb +0 -2
- data/spec/grape/loading_spec.rb +8 -10
- data/spec/grape/middleware/auth/base_spec.rb +0 -1
- data/spec/grape/middleware/auth/dsl_spec.rb +15 -8
- data/spec/grape/middleware/auth/strategies_spec.rb +60 -22
- data/spec/grape/middleware/base_spec.rb +24 -17
- data/spec/grape/middleware/error_spec.rb +8 -3
- data/spec/grape/middleware/exception_spec.rb +111 -163
- data/spec/grape/middleware/formatter_spec.rb +27 -8
- data/spec/grape/middleware/globals_spec.rb +7 -6
- data/spec/grape/middleware/stack_spec.rb +14 -14
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -3
- data/spec/grape/middleware/versioner/header_spec.rb +30 -15
- data/spec/grape/middleware/versioner/param_spec.rb +7 -3
- data/spec/grape/middleware/versioner/path_spec.rb +5 -3
- data/spec/grape/middleware/versioner_spec.rb +1 -3
- data/spec/grape/named_api_spec.rb +0 -2
- data/spec/grape/parser_spec.rb +4 -2
- data/spec/grape/path_spec.rb +52 -54
- data/spec/grape/presenters/presenter_spec.rb +7 -8
- data/spec/grape/request_spec.rb +6 -6
- data/spec/grape/util/inheritable_setting_spec.rb +7 -8
- data/spec/grape/util/inheritable_values_spec.rb +3 -3
- data/spec/grape/util/reverse_stackable_values_spec.rb +3 -2
- data/spec/grape/util/stackable_values_spec.rb +7 -6
- data/spec/grape/util/strict_hash_configuration_spec.rb +0 -1
- data/spec/grape/validations/attributes_doc_spec.rb +153 -0
- data/spec/grape/validations/attributes_iterator_spec.rb +0 -2
- data/spec/grape/validations/instance_behaivour_spec.rb +9 -12
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -2
- data/spec/grape/validations/params_scope_spec.rb +361 -96
- data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -3
- data/spec/grape/validations/types/array_coercer_spec.rb +0 -2
- data/spec/grape/validations/types/primitive_coercer_spec.rb +24 -9
- data/spec/grape/validations/types/set_coercer_spec.rb +0 -2
- data/spec/grape/validations/types_spec.rb +36 -10
- data/spec/grape/validations/validators/all_or_none_spec.rb +50 -58
- data/spec/grape/validations/validators/allow_blank_spec.rb +135 -141
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -58
- data/spec/grape/validations/validators/coerce_spec.rb +23 -24
- data/spec/grape/validations/validators/default_spec.rb +72 -80
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -79
- data/spec/grape/validations/validators/except_values_spec.rb +3 -5
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -79
- data/spec/grape/validations/validators/presence_spec.rb +16 -3
- data/spec/grape/validations/validators/regexp_spec.rb +25 -33
- data/spec/grape/validations/validators/same_as_spec.rb +14 -22
- data/spec/grape/validations/validators/values_spec.rb +182 -179
- data/spec/grape/validations_spec.rb +149 -80
- data/spec/integration/eager_load/eager_load_spec.rb +2 -2
- data/spec/integration/multi_json/json_spec.rb +1 -3
- data/spec/integration/multi_xml/xml_spec.rb +1 -3
- data/spec/shared/versioning_examples.rb +12 -9
- data/spec/spec_helper.rb +21 -6
- data/spec/support/basic_auth_encode_helpers.rb +1 -1
- metadata +126 -117
- data/lib/grape/validations/validators/all_or_none.rb +0 -15
- data/lib/grape/validations/validators/allow_blank.rb +0 -18
- data/lib/grape/validations/validators/as.rb +0 -16
- data/lib/grape/validations/validators/at_least_one_of.rb +0 -14
- data/lib/grape/validations/validators/coerce.rb +0 -91
- data/lib/grape/validations/validators/default.rb +0 -48
- data/lib/grape/validations/validators/exactly_one_of.rb +0 -16
- data/lib/grape/validations/validators/except_values.rb +0 -22
- data/lib/grape/validations/validators/mutual_exclusion.rb +0 -15
- data/lib/grape/validations/validators/presence.rb +0 -12
- data/lib/grape/validations/validators/regexp.rb +0 -13
- data/lib/grape/validations/validators/same_as.rb +0 -26
- data/lib/grape/validations/validators/values.rb +0 -83
- data/spec/support/eager_load.rb +0 -19
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: c13bf4d5de206b76e7cccbe4ffa454512986457b8f5d055cde0cfac5d4f164a9
         | 
| 4 | 
            +
              data.tar.gz: 1177df9af2a24d80e01366f3d705f29e4180898f4cc1ac7e0221e8412e36dcf1
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 32a0d1d9ae7d16b9760f8919814b2aa362ec95a666159a6dc8314946e8a9fd2461d8c074f705ac7afa21939d2a43bec4196a8b7803efdae967b2d01acd1ae77a
         | 
| 7 | 
            +
              data.tar.gz: 5ca9d54a6db6bc63107c2bd0b17cb747f293ec72bc3c0d57a7f7514f0c1122774bce82c5411f4fa19f1c7b435d2c3d1d87102e3f83ff5c31aa8a0dc531817e4d
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,70 @@ | |
| 1 | 
            +
            ### 1.7.0 (2022/12/20)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            #### Features
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * [#2233](https://github.com/ruby-grape/grape/pull/2233): Added `do_not_document!` for disabling documentation to internal APIs - [@dnesteryuk](https://github.com/dnesteryuk).
         | 
| 6 | 
            +
            * [#2235](https://github.com/ruby-grape/grape/pull/2235): Add support for Ruby 3.1 - [@petergoldstein](https://github.com/petergoldstein).
         | 
| 7 | 
            +
            * [#2248](https://github.com/ruby-grape/grape/pull/2248): Upgraded to rspec 3.11.0 - [@dblock](https://github.com/dblock).
         | 
| 8 | 
            +
            * [#2249](https://github.com/ruby-grape/grape/pull/2249): Split CI matrix, extract edge - [@dblock](https://github.com/dblock).
         | 
| 9 | 
            +
            * [#2249](https://github.com/ruby-grape/grape/pull/2251): Upgraded to RuboCop 1.25.1 - [@dblock](https://github.com/dblock).
         | 
| 10 | 
            +
            * [#2271](https://github.com/ruby-grape/grape/pull/2271): Fixed validation regression on Numeric type introduced in 1.3 - [@vasfed](https://github.com/Vasfed).
         | 
| 11 | 
            +
            * [#2267](https://github.com/ruby-grape/grape/pull/2267): Standardized English error messages - [@dblock](https://github.com/dblock).
         | 
| 12 | 
            +
            * [#2272](https://github.com/ruby-grape/grape/pull/2272): Added error on param init when provided type does not have `[]` coercion method, previously validation silently failed for any value - [@vasfed](https://github.com/Vasfed).
         | 
| 13 | 
            +
            * [#2274](https://github.com/ruby-grape/grape/pull/2274): Error middleware support using rack util's symbols as status - [@dhruvCW](https://github.com/dhruvCW).
         | 
| 14 | 
            +
            * [#2276](https://github.com/ruby-grape/grape/pull/2276): Fix exception super - [@ericproulx](https://github.com/ericproulx).
         | 
| 15 | 
            +
            * [#2285](https://github.com/ruby-grape/grape/pull/2285), [#2287](https://github.com/ruby-grape/grape/pull/2287): Added :evaluate_given to declared(params) - [@zysend](https://github.com/zysend).
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            #### Fixes
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            * [#2263](https://github.com/ruby-grape/grape/pull/2263): Explicitly require `bigdecimal` and `date` - [@dblock](https://github.com/dblock).
         | 
| 20 | 
            +
            * [#2222](https://github.com/ruby-grape/grape/pull/2222): Autoload types and validators - [@ericproulx](https://github.com/ericproulx).
         | 
| 21 | 
            +
            * [#2232](https://github.com/ruby-grape/grape/pull/2232): Fix kwargs support in shared params definition - [@dm1try](https://github.com/dm1try).
         | 
| 22 | 
            +
            * [#2229](https://github.com/ruby-grape/grape/pull/2229): Do not collect params in route settings - [@dnesteryuk](https://github.com/dnesteryuk).
         | 
| 23 | 
            +
            * [#2234](https://github.com/ruby-grape/grape/pull/2234): Remove non-UTF8 characters from format before generating JSON error - [@bschmeck](https://github.com/bschmeck).
         | 
| 24 | 
            +
            * [#2227](https://github.com/ruby-grape/grape/pull/2222): Rename `MissingGroupType` and `UnsupportedGroupType` exceptions - [@ericproulx](https://github.com/ericproulx).
         | 
| 25 | 
            +
            * [#2244](https://github.com/ruby-grape/grape/pull/2244): Fix a breaking change in `Grape::Validations` provided in 1.6.1 - [@dm1try](https://github.com/dm1try).
         | 
| 26 | 
            +
            * [#2250](https://github.com/ruby-grape/grape/pull/2250): Add deprecation warning for `UnsupportedGroupTypeError` and `MissingGroupTypeError` - [@ericproulx](https://github.com/ericproulx).
         | 
| 27 | 
            +
            * [#2256](https://github.com/ruby-grape/grape/pull/2256): Raise `Grape::Exceptions::MultipartPartLimitError` from Rack when too many files are uploaded - [@bschmeck](https://github.com/bschmeck).
         | 
| 28 | 
            +
            * [#2266](https://github.com/ruby-grape/grape/pull/2266): Fix code coverage - [@duffn](https://github.com/duffn).
         | 
| 29 | 
            +
            * [#2284](https://github.com/ruby-grape/grape/pull/2284): Fix an unexpected backtick - [@zysend](https://github.com/zysend).
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            ### 1.6.2 (2021/12/30)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            #### Fixes
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            * [#2219](https://github.com/ruby-grape/grape/pull/2219): Revert the changes for autoloading provided in 1.6.1 - [@dm1try](https://github.com/dm1try).
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            ### 1.6.1 (2021/12/28)
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            #### Features
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            * [#2196](https://github.com/ruby-grape/grape/pull/2196): Add support for `passwords_hashed` param for `digest_auth` - [@lHydra](https://github.com/lhydra).
         | 
| 42 | 
            +
            * [#2208](https://github.com/ruby-grape/grape/pull/2208): Added Rails 7 support - [@ericproulx](https://github.com/ericproulx).
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            #### Fixes
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            * [#2206](https://github.com/ruby-grape/grape/pull/2206): Require main active_support lib before any of its extension definitions - [@annih](https://github.com/Annih).
         | 
| 47 | 
            +
            * [#2193](https://github.com/ruby-grape/grape/pull/2193): Fixed the broken ruby-head NoMethodError spec - [@Jack12816](https://github.com/Jack12816).
         | 
| 48 | 
            +
            * [#2192](https://github.com/ruby-grape/grape/pull/2192): Memoize the result of Grape::Middleware::Base#response - [@Jack12816](https://github.com/Jack12816).
         | 
| 49 | 
            +
            * [#2200](https://github.com/ruby-grape/grape/pull/2200): Add validators module to all validators - [@ericproulx](https://github.com/ericproulx).
         | 
| 50 | 
            +
            * [#2202](https://github.com/ruby-grape/grape/pull/2202): Fix random mock spec error - [@ericproulx](https://github.com/ericproulx).
         | 
| 51 | 
            +
            * [#2203](https://github.com/ruby-grape/grape/pull/2203): Add rubocop-rspec - [@ericproulx](https://github.com/ericproulx).
         | 
| 52 | 
            +
            * [#2207](https://github.com/ruby-grape/grape/pull/2207): Autoload Validations/Validators - [@ericproulx](https://github.com/ericproulx).
         | 
| 53 | 
            +
            * [#2209](https://github.com/ruby-grape/grape/pull/2209): Autoload Validations/Types - [@ericproulx](https://github.com/ericproulx).
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            ### 1.6.0 (2021/10/04)
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            #### Features
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            * [#2190](https://github.com/ruby-grape/grape/pull/2190): Upgrade dev deps & drop Ruby 2.4.x support - [@dnesteryuk](https://github.com/dnesteryuk).
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            #### Fixes
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            * [#2176](https://github.com/ruby-grape/grape/pull/2176): Fix: OPTIONS fails if matching all routes - [@myxoh](https://github.com/myxoh).
         | 
| 64 | 
            +
            * [#2177](https://github.com/ruby-grape/grape/pull/2177): Fix: `default` validator fails if preceded by `as` validator - [@Catsuko](https://github.com/Catsuko).
         | 
| 65 | 
            +
            * [#2180](https://github.com/ruby-grape/grape/pull/2180): Call `super` in `API.inherited` - [@yogeshjain999](https://github.com/yogeshjain999).
         | 
| 66 | 
            +
            * [#2189](https://github.com/ruby-grape/grape/pull/2189): Fix: rename parameters when using `:as` (behaviour and grape-swagger documentation) - [@Jack12816](https://github.com/Jack12816).
         | 
| 67 | 
            +
             | 
| 1 68 | 
             
            ### 1.5.3 (2021/03/07)
         | 
| 2 69 |  | 
| 3 70 | 
             
            #### Fixes
         | 
    
        data/CONTRIBUTING.md
    CHANGED
    
    | @@ -35,6 +35,7 @@ bundle exec rake | |
| 35 35 | 
             
            Run tests against all supported versions of Rails.
         | 
| 36 36 |  | 
| 37 37 | 
             
            ```
         | 
| 38 | 
            +
            gem install appraisal
         | 
| 38 39 | 
             
            appraisal install
         | 
| 39 40 | 
             
            appraisal rake spec
         | 
| 40 41 | 
             
            ```
         | 
| @@ -118,7 +119,7 @@ Go back to your pull request after a few minutes and see whether it passed muste | |
| 118 119 |  | 
| 119 120 | 
             
            #### Be Patient
         | 
| 120 121 |  | 
| 121 | 
            -
            It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang  | 
| 122 | 
            +
            It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang in there!
         | 
| 122 123 |  | 
| 123 124 | 
             
            #### Thank You
         | 
| 124 125 |  | 
    
        data/README.md
    CHANGED
    
    | @@ -40,6 +40,7 @@ | |
| 40 40 | 
             
              - [Declared](#declared)
         | 
| 41 41 | 
             
              - [Include Parent Namespaces](#include-parent-namespaces)
         | 
| 42 42 | 
             
              - [Include Missing](#include-missing)
         | 
| 43 | 
            +
              - [Evaluate Given](#evaluate-given)
         | 
| 43 44 | 
             
            - [Parameter Validation and Coercion](#parameter-validation-and-coercion)
         | 
| 44 45 | 
             
              - [Supported Parameter Types](#supported-parameter-types)
         | 
| 45 46 | 
             
              - [Integer/Fixnum and Coercions](#integerfixnum-and-coercions)
         | 
| @@ -158,7 +159,7 @@ content negotiation, versioning and much more. | |
| 158 159 |  | 
| 159 160 | 
             
            ## Stable Release
         | 
| 160 161 |  | 
| 161 | 
            -
            You're reading the documentation for the stable release of Grape,  | 
| 162 | 
            +
            You're reading the documentation for the stable release of Grape, 1.7.0.
         | 
| 162 163 | 
             
            Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
         | 
| 163 164 |  | 
| 164 165 | 
             
            ## Project Resources
         | 
| @@ -174,21 +175,13 @@ Available as part of the Tidelift Subscription. | |
| 174 175 |  | 
| 175 176 | 
             
            The maintainers of Grape are working with Tidelift to deliver commercial support and maintenance. Save time, reduce risk, and improve code health, while paying the maintainers of Grape. Click [here](https://tidelift.com/subscription/request-a-demo?utm_source=rubygems-grape&utm_medium=referral&utm_campaign=enterprise) for more details.
         | 
| 176 177 |  | 
| 177 | 
            -
            In 2020, we plan to use the money towards gathering Grape contributors for dinner in New York City.
         | 
| 178 | 
            -
             | 
| 179 178 | 
             
            ## Installation
         | 
| 180 179 |  | 
| 181 180 | 
             
            Ruby 2.4 or newer is required.
         | 
| 182 181 |  | 
| 183 | 
            -
            Grape is available as a gem, to install it  | 
| 184 | 
            -
             | 
| 185 | 
            -
                gem install grape
         | 
| 186 | 
            -
             | 
| 187 | 
            -
            If you're using Bundler, add the gem to Gemfile.
         | 
| 188 | 
            -
             | 
| 189 | 
            -
                gem 'grape'
         | 
| 182 | 
            +
            Grape is available as a gem, to install it run:
         | 
| 190 183 |  | 
| 191 | 
            -
             | 
| 184 | 
            +
                bundle add grape
         | 
| 192 185 |  | 
| 193 186 | 
             
            ## Basic Usage
         | 
| 194 187 |  | 
| @@ -800,6 +793,7 @@ Grape allows you to access only the parameters that have been declared by your ` | |
| 800 793 |  | 
| 801 794 | 
             
              * Filter out the params that have been passed, but are not allowed.
         | 
| 802 795 | 
             
              * Include any optional params that are declared but not passed.
         | 
| 796 | 
            +
              * Perform any parameter renaming on the resulting hash.
         | 
| 803 797 |  | 
| 804 798 | 
             
            Consider the following API endpoint:
         | 
| 805 799 |  | 
| @@ -994,8 +988,10 @@ curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d | |
| 994 988 | 
             
            ````json
         | 
| 995 989 | 
             
            {
         | 
| 996 990 | 
             
              "declared_params": {
         | 
| 997 | 
            -
                " | 
| 998 | 
            -
             | 
| 991 | 
            +
                "user": {
         | 
| 992 | 
            +
                  "first_name": "first name",
         | 
| 993 | 
            +
                  "last_name": null
         | 
| 994 | 
            +
                }
         | 
| 999 995 | 
             
              }
         | 
| 1000 996 | 
             
            }
         | 
| 1001 997 | 
             
            ````
         | 
| @@ -1082,6 +1078,102 @@ curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d | |
| 1082 1078 | 
             
            }
         | 
| 1083 1079 | 
             
            ````
         | 
| 1084 1080 |  | 
| 1081 | 
            +
            ### Evaluate Given
         | 
| 1082 | 
            +
             | 
| 1083 | 
            +
            By default `declared(params)` will not evaluate `given` and return all parameters. Use `evaluate_given` to evaluate all `given` blocks and return only parameters that satisfy `given` conditions. Consider the following API:
         | 
| 1084 | 
            +
             | 
| 1085 | 
            +
            ````ruby
         | 
| 1086 | 
            +
            format :json
         | 
| 1087 | 
            +
             | 
| 1088 | 
            +
            params do
         | 
| 1089 | 
            +
              optional :child_id, type: Integer
         | 
| 1090 | 
            +
              given :child_id do
         | 
| 1091 | 
            +
                requires :father_id, type: Integer
         | 
| 1092 | 
            +
              end
         | 
| 1093 | 
            +
            end
         | 
| 1094 | 
            +
             | 
| 1095 | 
            +
            post 'child' do
         | 
| 1096 | 
            +
              { 'declared_params' => declared(params, evaluate_given: true) }
         | 
| 1097 | 
            +
            end
         | 
| 1098 | 
            +
            ````
         | 
| 1099 | 
            +
             | 
| 1100 | 
            +
            **Request**
         | 
| 1101 | 
            +
             | 
| 1102 | 
            +
            ````bash
         | 
| 1103 | 
            +
            curl -X POST -H "Content-Type: application/json" localhost:9292/child -d '{"father_id": 1}'
         | 
| 1104 | 
            +
            ````
         | 
| 1105 | 
            +
             | 
| 1106 | 
            +
            **Response with evaluate_given:false**
         | 
| 1107 | 
            +
             | 
| 1108 | 
            +
            ````json
         | 
| 1109 | 
            +
            {
         | 
| 1110 | 
            +
              "declared_params": {
         | 
| 1111 | 
            +
                "child_id": null,
         | 
| 1112 | 
            +
                "father_id": 1
         | 
| 1113 | 
            +
              }
         | 
| 1114 | 
            +
            }
         | 
| 1115 | 
            +
            ````
         | 
| 1116 | 
            +
             | 
| 1117 | 
            +
            **Response with evaluate_given:true**
         | 
| 1118 | 
            +
             | 
| 1119 | 
            +
            ````json
         | 
| 1120 | 
            +
            {
         | 
| 1121 | 
            +
              "declared_params": {
         | 
| 1122 | 
            +
                "child_id": null
         | 
| 1123 | 
            +
              }
         | 
| 1124 | 
            +
            }
         | 
| 1125 | 
            +
            ````
         | 
| 1126 | 
            +
             | 
| 1127 | 
            +
            It also works on nested hashes:
         | 
| 1128 | 
            +
             | 
| 1129 | 
            +
            ````ruby
         | 
| 1130 | 
            +
            format :json
         | 
| 1131 | 
            +
             | 
| 1132 | 
            +
            params do
         | 
| 1133 | 
            +
              requires :child, type: Hash do
         | 
| 1134 | 
            +
                optional :child_id, type: Integer
         | 
| 1135 | 
            +
                given :child_id do
         | 
| 1136 | 
            +
                  requires :father_id, type: Integer
         | 
| 1137 | 
            +
                end
         | 
| 1138 | 
            +
              end
         | 
| 1139 | 
            +
            end
         | 
| 1140 | 
            +
             | 
| 1141 | 
            +
            post 'child' do
         | 
| 1142 | 
            +
              { 'declared_params' => declared(params, evaluate_given: true) }
         | 
| 1143 | 
            +
            end
         | 
| 1144 | 
            +
            ````
         | 
| 1145 | 
            +
             | 
| 1146 | 
            +
            **Request**
         | 
| 1147 | 
            +
             | 
| 1148 | 
            +
            ````bash
         | 
| 1149 | 
            +
            curl -X POST -H "Content-Type: application/json" localhost:9292/child -d '{"child": {"father_id": 1}}'
         | 
| 1150 | 
            +
            ````
         | 
| 1151 | 
            +
             | 
| 1152 | 
            +
            **Response with evaluate_given:false**
         | 
| 1153 | 
            +
             | 
| 1154 | 
            +
            ````json
         | 
| 1155 | 
            +
            {
         | 
| 1156 | 
            +
              "declared_params": {
         | 
| 1157 | 
            +
                "child": {
         | 
| 1158 | 
            +
                  "child_id": null,
         | 
| 1159 | 
            +
                  "father_id": 1
         | 
| 1160 | 
            +
                }
         | 
| 1161 | 
            +
              }
         | 
| 1162 | 
            +
            }
         | 
| 1163 | 
            +
            ````
         | 
| 1164 | 
            +
             | 
| 1165 | 
            +
            **Response with evaluate_given:true**
         | 
| 1166 | 
            +
             | 
| 1167 | 
            +
            ````json
         | 
| 1168 | 
            +
            {
         | 
| 1169 | 
            +
              "declared_params": {
         | 
| 1170 | 
            +
                "child": {
         | 
| 1171 | 
            +
                  "child_id": null
         | 
| 1172 | 
            +
                }
         | 
| 1173 | 
            +
              }
         | 
| 1174 | 
            +
            }
         | 
| 1175 | 
            +
            ````
         | 
| 1176 | 
            +
             | 
| 1085 1177 | 
             
            ## Parameter Validation and Coercion
         | 
| 1086 1178 |  | 
| 1087 1179 | 
             
            You can define validations and coercion options for your parameters using a `params` block.
         | 
| @@ -1450,7 +1542,7 @@ resource :users do | |
| 1450 1542 | 
             
            end
         | 
| 1451 1543 | 
             
            ```
         | 
| 1452 1544 |  | 
| 1453 | 
            -
            The value passed to `as` will be the key when calling ` | 
| 1545 | 
            +
            The value passed to `as` will be the key when calling `declared(params)`.
         | 
| 1454 1546 |  | 
| 1455 1547 | 
             
            ### Built-in Validators
         | 
| 1456 1548 |  | 
| @@ -1529,6 +1621,14 @@ end | |
| 1529 1621 |  | 
| 1530 1622 | 
             
            While Procs are convenient for single cases, consider using [Custom Validators](#custom-validators) in cases where a validation is used more than once.
         | 
| 1531 1623 |  | 
| 1624 | 
            +
            Note that [allow_blank](#allow_blank) validator applies while using `:values`. In the following example the absence of `:allow_blank` does not prevent `:state` from receiving blank values because `:allow_blank` defaults to `true`.
         | 
| 1625 | 
            +
             | 
| 1626 | 
            +
            ```ruby
         | 
| 1627 | 
            +
            params do
         | 
| 1628 | 
            +
              requires :state, type: Symbol, values: [:active, :inactive]
         | 
| 1629 | 
            +
            end
         | 
| 1630 | 
            +
            ```
         | 
| 1631 | 
            +
             | 
| 1532 1632 | 
             
            #### `except_values`
         | 
| 1533 1633 |  | 
| 1534 1634 | 
             
            Parameters can be restricted from having a specific set of values with the `:except_values` option.
         | 
| @@ -1731,10 +1831,10 @@ end | |
| 1731 1831 | 
             
            ### Custom Validators
         | 
| 1732 1832 |  | 
| 1733 1833 | 
             
            ```ruby
         | 
| 1734 | 
            -
            class AlphaNumeric < Grape::Validations::Base
         | 
| 1834 | 
            +
            class AlphaNumeric < Grape::Validations::Validators::Base
         | 
| 1735 1835 | 
             
              def validate_param!(attr_name, params)
         | 
| 1736 1836 | 
             
                unless params[attr_name] =~ /\A[[:alnum:]]+\z/
         | 
| 1737 | 
            -
                   | 
| 1837 | 
            +
                  raise Grape::Exceptions::Validation.new params: [@scope.full_name(attr_name)], message: 'must consist of alpha-numeric characters'
         | 
| 1738 1838 | 
             
                end
         | 
| 1739 1839 | 
             
              end
         | 
| 1740 1840 | 
             
            end
         | 
| @@ -1749,10 +1849,10 @@ end | |
| 1749 1849 | 
             
            You can also create custom classes that take parameters.
         | 
| 1750 1850 |  | 
| 1751 1851 | 
             
            ```ruby
         | 
| 1752 | 
            -
            class Length < Grape::Validations::Base
         | 
| 1852 | 
            +
            class Length < Grape::Validations::Validators::Base
         | 
| 1753 1853 | 
             
              def validate_param!(attr_name, params)
         | 
| 1754 1854 | 
             
                unless params[attr_name].length <= @option
         | 
| 1755 | 
            -
                   | 
| 1855 | 
            +
                  raise Grape::Exceptions::Validation.new params: [@scope.full_name(attr_name)], message: "must be at the most #{@option} characters long"
         | 
| 1756 1856 | 
             
                end
         | 
| 1757 1857 | 
             
              end
         | 
| 1758 1858 | 
             
            end
         | 
| @@ -1767,7 +1867,7 @@ end | |
| 1767 1867 | 
             
            You can also create custom validation that use request to validate the attribute. For example if you want to have parameters that are available to only admins, you can do the following.
         | 
| 1768 1868 |  | 
| 1769 1869 | 
             
            ```ruby
         | 
| 1770 | 
            -
            class Admin < Grape::Validations::Base
         | 
| 1870 | 
            +
            class Admin < Grape::Validations::Validators::Base
         | 
| 1771 1871 | 
             
              def validate(request)
         | 
| 1772 1872 | 
             
                # return if the param we are checking was not in request
         | 
| 1773 1873 | 
             
                # @attrs is a list containing the attribute we are currently validating
         | 
| @@ -1778,7 +1878,7 @@ class Admin < Grape::Validations::Base | |
| 1778 1878 | 
             
                return unless @option
         | 
| 1779 1879 | 
             
                # check if user is admin or not
         | 
| 1780 1880 | 
             
                # as an example get a token from request and check if it's admin or not
         | 
| 1781 | 
            -
                 | 
| 1881 | 
            +
                raise Grape::Exceptions::Validation.new params: @attrs, message: 'Can not set admin-only field.' unless request.headers['X-Access-Token'] == 'admin'
         | 
| 1782 1882 | 
             
              end
         | 
| 1783 1883 | 
             
            end
         | 
| 1784 1884 | 
             
            ```
         | 
| @@ -2237,6 +2337,18 @@ params do | |
| 2237 2337 | 
             
            end
         | 
| 2238 2338 | 
             
            ```
         | 
| 2239 2339 |  | 
| 2340 | 
            +
            If documentation isn't needed (for instance, it is an internal API), documentation can be disabled.
         | 
| 2341 | 
            +
             | 
| 2342 | 
            +
            ```ruby
         | 
| 2343 | 
            +
            class API < Grape::API
         | 
| 2344 | 
            +
              do_not_document!
         | 
| 2345 | 
            +
             | 
| 2346 | 
            +
              # endpoints...
         | 
| 2347 | 
            +
            end
         | 
| 2348 | 
            +
            ```
         | 
| 2349 | 
            +
             | 
| 2350 | 
            +
            In this case, Grape won't create objects related to documentation which are retained in RAM forever.
         | 
| 2351 | 
            +
             | 
| 2240 2352 | 
             
            ## Cookies
         | 
| 2241 2353 |  | 
| 2242 2354 | 
             
            You can set, get and delete your cookies very simply using `cookies` method.
         | 
| @@ -3285,12 +3397,20 @@ http_basic do |username, password| | |
| 3285 3397 | 
             
            end
         | 
| 3286 3398 | 
             
            ```
         | 
| 3287 3399 |  | 
| 3400 | 
            +
            Digest auth supports clear-text passwords and password hashes.
         | 
| 3401 | 
            +
             | 
| 3288 3402 | 
             
            ```ruby
         | 
| 3289 3403 | 
             
            http_digest({ realm: 'Test Api', opaque: 'app secret' }) do |username|
         | 
| 3290 3404 | 
             
              # lookup the user's password here
         | 
| 3291 3405 | 
             
            end
         | 
| 3292 3406 | 
             
            ```
         | 
| 3293 3407 |  | 
| 3408 | 
            +
            ```ruby
         | 
| 3409 | 
            +
            http_digest(realm: { realm: 'Test Api', opaque: 'app secret', passwords_hashed: true }) do |username|
         | 
| 3410 | 
            +
              # lookup the user's password hash here
         | 
| 3411 | 
            +
            end
         | 
| 3412 | 
            +
            ```
         | 
| 3413 | 
            +
             | 
| 3294 3414 | 
             
            ### Register custom middleware for authentication
         | 
| 3295 3415 |  | 
| 3296 3416 | 
             
            Grape can use custom Middleware for authentication. How to implement these
         | 
| @@ -3641,6 +3761,14 @@ You can access the controller params, headers, and helpers through the context w | |
| 3641 3761 | 
             
            Note that when you're using Grape mounted on Rails you don't have to use Rails middleware because it's already included into your middleware stack.
         | 
| 3642 3762 | 
             
            You only have to implement the helpers to access the specific `env` variable.
         | 
| 3643 3763 |  | 
| 3764 | 
            +
            If you are using a custom application that is inherited from `Rails::Application` and need to insert a new middleware among the ones initiated via Rails, you will need to register it manually in your custom application class.
         | 
| 3765 | 
            +
             | 
| 3766 | 
            +
            ```ruby
         | 
| 3767 | 
            +
            class Company::Application < Rails::Application
         | 
| 3768 | 
            +
              config.middleware.insert_before(Rack::Attack, Middleware::ApiLogger)
         | 
| 3769 | 
            +
            end
         | 
| 3770 | 
            +
            ```
         | 
| 3771 | 
            +
             | 
| 3644 3772 | 
             
            ### Remote IP
         | 
| 3645 3773 |  | 
| 3646 3774 | 
             
            By default you can access remote IP with `request.ip`. This is the remote IP address implemented by Rack. Sometimes it is desirable to get the remote IP [Rails-style](http://stackoverflow.com/questions/10997005/whats-the-difference-between-request-remote-ip-and-request-ip-in-rails) with `ActionDispatch::RemoteIp`.
         | 
| @@ -3674,7 +3802,7 @@ Use `rack-test` and define your API as `app`. | |
| 3674 3802 | 
             
            You can test a Grape API with RSpec by making HTTP requests and examining the response.
         | 
| 3675 3803 |  | 
| 3676 3804 | 
             
            ```ruby
         | 
| 3677 | 
            -
             | 
| 3805 | 
            +
             | 
| 3678 3806 |  | 
| 3679 3807 | 
             
            describe Twitter::API do
         | 
| 3680 3808 | 
             
              include Rack::Test::Methods
         | 
| @@ -3945,6 +4073,7 @@ Grape integrates with following third-party tools: | |
| 3945 4073 | 
             
            * **[Skylight](https://www.skylight.io/)** - [skylight](https://github.com/skylightio/skylight-ruby) gem, [documentation](https://docs.skylight.io/grape/)
         | 
| 3946 4074 | 
             
            * **[AppSignal](https://www.appsignal.com)** - [appsignal-ruby](https://github.com/appsignal/appsignal-ruby) gem, [documentation](http://docs.appsignal.com/getting-started/supported-frameworks.html#grape)
         | 
| 3947 4075 | 
             
            * **[ElasticAPM](https://www.elastic.co/products/apm)** - [elastic-apm](https://github.com/elastic/apm-agent-ruby) gem, [documentation](https://www.elastic.co/guide/en/apm/agent/ruby/3.x/getting-started-rack.html#getting-started-grape)
         | 
| 4076 | 
            +
            * **[Datadog APM](https://docs.datadoghq.com/tracing/)** - [ddtrace](https://github.com/datadog/dd-trace-rb) gem, [documentation](https://docs.datadoghq.com/tracing/setup_overview/setup/ruby/#grape)
         | 
| 3948 4077 |  | 
| 3949 4078 | 
             
            ## Contributing to Grape
         | 
| 3950 4079 |  | 
    
        data/UPGRADING.md
    CHANGED
    
    | @@ -1,13 +1,68 @@ | |
| 1 1 | 
             
            Upgrading Grape
         | 
| 2 2 | 
             
            ===============
         | 
| 3 3 |  | 
| 4 | 
            +
            ### Upgrading to >= 1.7.0
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            #### Exceptions renaming
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            The following exceptions has been renamed for consistency through exceptions naming :
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            * `MissingGroupTypeError` => `MissingGroupType`
         | 
| 11 | 
            +
            * `UnsupportedGroupTypeError` => `UnsupportedGroupType`
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            See [#2227](https://github.com/ruby-grape/grape/pull/2227) for more information.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            #### Handling Multipart Limit Errors
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            Rack supports a configurable limit on the number of files created from multipart parameters (`Rack::Utils.multipart_part_limit`) and raises an error if params are received that create too many files.  If you were handling the Rack error directly, Grape now wraps that error in `Grape::Execeptions::TooManyMultipartFiles`.  Additionally, Grape will return a 413 status code if the exception goes unhandled.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            ### Upgrading to >= 1.6.0
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            #### Parameter renaming with :as
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            Prior to 1.6.0 the [parameter renaming](https://github.com/ruby-grape/grape#renaming) with `:as` was directly touching the request payload ([`#params`](https://github.com/ruby-grape/grape#parameters)) while duplicating the old and the new key to be both available in the hash. This allowed clients to bypass any validation in case they knew the internal name of the parameter.  Unfortunately, in combination with [grape-swagger](https://github.com/ruby-grape/grape-swagger) the internal name (name set with `:as`) of the parameters were documented.
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            This behavior was fixed. Parameter renaming is now done when using the [`#declared(params)`](https://github.com/ruby-grape/grape#declared) parameters helper. This stops confusing validation/coercion behavior.
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            Here comes an illustration of the old and new behaviour as code:
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            ```ruby
         | 
| 30 | 
            +
            # (1) Rename a to b, while client sends +a+
         | 
| 31 | 
            +
            optional :a, type: Integer, as: :b
         | 
| 32 | 
            +
            params = { a: 1 }
         | 
| 33 | 
            +
            declared(params, include_missing: false)
         | 
| 34 | 
            +
            # expected => { b: 1 }
         | 
| 35 | 
            +
            # actual   => { b: 1 }
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            # (2) Rename a to b, while client sends +b+
         | 
| 38 | 
            +
            optional :a, type: Integer, as: :b, values: [1, 2, 3]
         | 
| 39 | 
            +
            params = { b: '5' }
         | 
| 40 | 
            +
            declared(params, include_missing: false)
         | 
| 41 | 
            +
            # expected => { }        (>= 1.6.0)
         | 
| 42 | 
            +
            # actual   => { b: '5' } (uncasted, unvalidated, <= 1.5.3)
         | 
| 43 | 
            +
            ```
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            Another implication of this change is the dependent parameter resolution. Prior to 1.6.0 the following code produced a `Grape::Exceptions::UnknownParameter` because `:a` was replaced by `:b`:
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            ```ruby
         | 
| 48 | 
            +
            params do
         | 
| 49 | 
            +
              optional :a, as: :b
         | 
| 50 | 
            +
              given :a do # (<= 1.5.3 you had to reference +:b+ here to make it work)
         | 
| 51 | 
            +
                requires :c
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
            end
         | 
| 54 | 
            +
            ```
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            This code now works without any errors, as the renaming is just an internal behaviour of the `#declared(params)` parameter helper.
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            See [#2189](https://github.com/ruby-grape/grape/pull/2189) for more information.
         | 
| 4 59 |  | 
| 5 60 | 
             
            ### Upgrading to >= 1.5.3
         | 
| 6 61 |  | 
| 7 | 
            -
             | 
| 62 | 
            +
            #### Nil value and coercion
         | 
| 8 63 |  | 
| 9 64 | 
             
            Prior to 1.2.5 version passing a `nil` value for a parameter with a custom coercer would invoke the coercer, and not passing a parameter would not invoke it.
         | 
| 10 | 
            -
            This behavior was not tested or documented. Version 1.3.0 quietly changed this behavior, in  | 
| 65 | 
            +
            This behavior was not tested or documented. Version 1.3.0 quietly changed this behavior, in that `nil` values skipped the coercion. Version 1.5.3 fixes and documents this as follows:
         | 
| 11 66 |  | 
| 12 67 | 
             
            ```ruby
         | 
| 13 68 | 
             
            class Api < Grape::API
         | 
| @@ -157,13 +212,13 @@ end | |
| 157 212 |  | 
| 158 213 | 
             
            #### Nil values for structures
         | 
| 159 214 |  | 
| 160 | 
            -
            Nil values always been a special case when dealing with types especially with the following structures:
         | 
| 215 | 
            +
            Nil values have always been a special case when dealing with types, especially with the following structures:
         | 
| 161 216 |  | 
| 162 217 | 
             
            - Array
         | 
| 163 218 | 
             
            - Hash
         | 
| 164 219 | 
             
            - Set
         | 
| 165 220 |  | 
| 166 | 
            -
            The behavior for these structures has  | 
| 221 | 
            +
            The behavior for these structures has changed throughout the latest releases. For example:
         | 
| 167 222 |  | 
| 168 223 | 
             
            ```ruby
         | 
| 169 224 | 
             
            class Api < Grape::API
         | 
| @@ -216,6 +271,8 @@ end | |
| 216 271 |  | 
| 217 272 | 
             
            ### Upgrading to >= 1.3.0
         | 
| 218 273 |  | 
| 274 | 
            +
            You will need to upgrade to this version if you depend on `rack >= 2.1.0`.
         | 
| 275 | 
            +
             | 
| 219 276 | 
             
            #### Ruby
         | 
| 220 277 |  | 
| 221 278 | 
             
            After adding dry-types, Ruby 2.4 or newer is required.
         | 
    
        data/grape.gemspec
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            $LOAD_PATH.unshift File.expand_path(' | 
| 3 | 
            +
            $LOAD_PATH.unshift File.expand_path('lib', __dir__)
         | 
| 4 4 | 
             
            require 'grape/version'
         | 
| 5 5 |  | 
| 6 6 | 
             
            Gem::Specification.new do |s|
         | 
| @@ -14,10 +14,10 @@ Gem::Specification.new do |s| | |
| 14 14 | 
             
              s.description = 'A Ruby framework for rapid API development with great conventions.'
         | 
| 15 15 | 
             
              s.license     = 'MIT'
         | 
| 16 16 | 
             
              s.metadata    = {
         | 
| 17 | 
            -
                'bug_tracker_uri' | 
| 18 | 
            -
                'changelog_uri' | 
| 17 | 
            +
                'bug_tracker_uri' => 'https://github.com/ruby-grape/grape/issues',
         | 
| 18 | 
            +
                'changelog_uri' => "https://github.com/ruby-grape/grape/blob/v#{s.version}/CHANGELOG.md",
         | 
| 19 19 | 
             
                'documentation_uri' => "https://www.rubydoc.info/gems/grape/#{s.version}",
         | 
| 20 | 
            -
                'source_code_uri' | 
| 20 | 
            +
                'source_code_uri' => "https://github.com/ruby-grape/grape/tree/v#{s.version}"
         | 
| 21 21 | 
             
              }
         | 
| 22 22 |  | 
| 23 23 | 
             
              s.add_runtime_dependency 'activesupport'
         | 
| @@ -32,5 +32,5 @@ Gem::Specification.new do |s| | |
| 32 32 | 
             
              s.files        += Dir['lib/**/*']
         | 
| 33 33 | 
             
              s.test_files    = Dir['spec/**/*']
         | 
| 34 34 | 
             
              s.require_paths = ['lib']
         | 
| 35 | 
            -
              s.required_ruby_version = '>= 2. | 
| 35 | 
            +
              s.required_ruby_version = '>= 2.5.0'
         | 
| 36 36 | 
             
            end
         | 
    
        data/lib/grape/api/instance.rb
    CHANGED
    
    | @@ -10,12 +10,11 @@ module Grape | |
| 10 10 | 
             
                  include Grape::DSL::API
         | 
| 11 11 |  | 
| 12 12 | 
             
                  class << self
         | 
| 13 | 
            -
                    attr_reader :instance
         | 
| 14 | 
            -
                    attr_reader :base
         | 
| 13 | 
            +
                    attr_reader :instance, :base
         | 
| 15 14 | 
             
                    attr_accessor :configuration
         | 
| 16 15 |  | 
| 17 16 | 
             
                    def given(conditional_option, &block)
         | 
| 18 | 
            -
                      evaluate_as_instance_with_configuration(block, lazy: true) if conditional_option &&  | 
| 17 | 
            +
                      evaluate_as_instance_with_configuration(block, lazy: true) if conditional_option && block
         | 
| 19 18 | 
             
                    end
         | 
| 20 19 |  | 
| 21 20 | 
             
                    def mounted(&block)
         | 
| @@ -28,7 +27,7 @@ module Grape | |
| 28 27 | 
             
                    end
         | 
| 29 28 |  | 
| 30 29 | 
             
                    def to_s
         | 
| 31 | 
            -
                       | 
| 30 | 
            +
                      base&.to_s || super
         | 
| 32 31 | 
             
                    end
         | 
| 33 32 |  | 
| 34 33 | 
             
                    def base_instance?
         | 
| @@ -82,6 +81,7 @@ module Grape | |
| 82 81 |  | 
| 83 82 | 
             
                    def compile!
         | 
| 84 83 | 
             
                      return if instance
         | 
| 84 | 
            +
             | 
| 85 85 | 
             
                      LOCK.synchronize { compile unless instance }
         | 
| 86 86 | 
             
                    end
         | 
| 87 87 |  | 
| @@ -101,9 +101,9 @@ module Grape | |
| 101 101 | 
             
                    # block passed in. Allows for simple 'before' setups
         | 
| 102 102 | 
             
                    # of settings stack pushes.
         | 
| 103 103 | 
             
                    def nest(*blocks, &block)
         | 
| 104 | 
            -
                      blocks. | 
| 104 | 
            +
                      blocks.compact!
         | 
| 105 105 | 
             
                      if blocks.any?
         | 
| 106 | 
            -
                        evaluate_as_instance_with_configuration(block) if  | 
| 106 | 
            +
                        evaluate_as_instance_with_configuration(block) if block
         | 
| 107 107 | 
             
                        blocks.each { |b| evaluate_as_instance_with_configuration(b) }
         | 
| 108 108 | 
             
                        reset_validations!
         | 
| 109 109 | 
             
                      else
         | 
| @@ -114,9 +114,7 @@ module Grape | |
| 114 114 | 
             
                    def evaluate_as_instance_with_configuration(block, lazy: false)
         | 
| 115 115 | 
             
                      lazy_block = Grape::Util::LazyBlock.new do |configuration|
         | 
| 116 116 | 
             
                        value_for_configuration = configuration
         | 
| 117 | 
            -
                        if value_for_configuration.respond_to?(:lazy?) && value_for_configuration.lazy?
         | 
| 118 | 
            -
                          self.configuration = value_for_configuration.evaluate
         | 
| 119 | 
            -
                        end
         | 
| 117 | 
            +
                        self.configuration = value_for_configuration.evaluate if value_for_configuration.respond_to?(:lazy?) && value_for_configuration.lazy?
         | 
| 120 118 | 
             
                        response = instance_eval(&block)
         | 
| 121 119 | 
             
                        self.configuration = value_for_configuration
         | 
| 122 120 | 
             
                        response
         | 
| @@ -179,7 +177,8 @@ module Grape | |
| 179 177 | 
             
                  # X-Cascade. Default :cascade is true.
         | 
| 180 178 | 
             
                  def cascade?
         | 
| 181 179 | 
             
                    return self.class.namespace_inheritable(:cascade) if self.class.inheritable_setting.namespace_inheritable.key?(:cascade)
         | 
| 182 | 
            -
                    return self.class.namespace_inheritable(:version_options)[:cascade] if self.class.namespace_inheritable(:version_options) | 
| 180 | 
            +
                    return self.class.namespace_inheritable(:version_options)[:cascade] if self.class.namespace_inheritable(:version_options)&.key?(:cascade)
         | 
| 181 | 
            +
             | 
| 183 182 | 
             
                    true
         | 
| 184 183 | 
             
                  end
         | 
| 185 184 |  | 
| @@ -200,17 +199,15 @@ module Grape | |
| 200 199 | 
             
                    without_root_prefix do
         | 
| 201 200 | 
             
                      without_versioning do
         | 
| 202 201 | 
             
                        versioned_route_configs.each do |config|
         | 
| 202 | 
            +
                          next if config[:options][:matching_wildchar]
         | 
| 203 | 
            +
             | 
| 203 204 | 
             
                          allowed_methods = config[:methods].dup
         | 
| 204 205 |  | 
| 205 | 
            -
                           | 
| 206 | 
            -
                            allowed_methods |= [Grape::Http::Headers::HEAD] if allowed_methods.include?(Grape::Http::Headers::GET)
         | 
| 207 | 
            -
                          end
         | 
| 206 | 
            +
                          allowed_methods |= [Grape::Http::Headers::HEAD] if !self.class.namespace_inheritable(:do_not_route_head) && allowed_methods.include?(Grape::Http::Headers::GET)
         | 
| 208 207 |  | 
| 209 208 | 
             
                          allow_header = (self.class.namespace_inheritable(:do_not_route_options) ? allowed_methods : [Grape::Http::Headers::OPTIONS] | allowed_methods)
         | 
| 210 209 |  | 
| 211 | 
            -
                          unless self.class.namespace_inheritable(:do_not_route_options) || allowed_methods.include?(Grape::Http::Headers::OPTIONS)
         | 
| 212 | 
            -
                            config[:endpoint].options[:options_route_enabled] = true
         | 
| 213 | 
            -
                          end
         | 
| 210 | 
            +
                          config[:endpoint].options[:options_route_enabled] = true unless self.class.namespace_inheritable(:do_not_route_options) || allowed_methods.include?(Grape::Http::Headers::OPTIONS)
         | 
| 214 211 |  | 
| 215 212 | 
             
                          attributes = config.merge(allowed_methods: allowed_methods, allow_header: allow_header)
         | 
| 216 213 | 
             
                          generate_not_allowed_method(config[:pattern], **attributes)
         | 
| @@ -228,7 +225,7 @@ module Grape | |
| 228 225 | 
             
                      last_route        = routes.last # Most of the configuration is taken from the last endpoint
         | 
| 229 226 | 
             
                      matching_wildchar = routes.any? { |route| route.request_method == '*' }
         | 
| 230 227 | 
             
                      {
         | 
| 231 | 
            -
                        options: {},
         | 
| 228 | 
            +
                        options: { matching_wildchar: matching_wildchar },
         | 
| 232 229 | 
             
                        pattern: last_route.pattern,
         | 
| 233 230 | 
             
                        requirements: last_route.requirements,
         | 
| 234 231 | 
             
                        path: last_route.origin,
         | 
| @@ -248,7 +245,6 @@ module Grape | |
| 248 245 | 
             
                        Grape::Http::Headers::SUPPORTED_METHODS_WITHOUT_OPTIONS
         | 
| 249 246 | 
             
                      end
         | 
| 250 247 | 
             
                    not_allowed_methods = supported_methods - allowed_methods
         | 
| 251 | 
            -
                    return if not_allowed_methods.empty?
         | 
| 252 248 | 
             
                    @router.associate_routes(pattern, not_allowed_methods: not_allowed_methods, **attributes)
         | 
| 253 249 | 
             
                  end
         | 
| 254 250 |  |