grape 4.0.0 → 4.1.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 +108 -1
- data/README.md +195 -95
- data/UPGRADING.md +364 -0
- data/grape.gemspec +1 -1
- data/lib/grape/api/instance.rb +57 -30
- data/lib/grape/api.rb +52 -18
- data/lib/grape/content_types.rb +26 -9
- data/lib/grape/cookies.rb +1 -1
- data/lib/grape/declared_params_handler.rb +35 -7
- data/lib/grape/dsl/declared.rb +5 -4
- data/lib/grape/dsl/desc.rb +1 -2
- data/lib/grape/dsl/entity.rb +35 -19
- data/lib/grape/dsl/headers.rb +3 -3
- data/lib/grape/dsl/helpers.rb +5 -8
- data/lib/grape/dsl/inside_route.rb +33 -27
- data/lib/grape/dsl/logger.rb +10 -4
- data/lib/grape/dsl/middleware.rb +4 -9
- data/lib/grape/dsl/mounting.rb +149 -0
- data/lib/grape/dsl/parameters.rb +78 -104
- data/lib/grape/dsl/request_response.rb +35 -22
- data/lib/grape/dsl/routing.rb +17 -191
- data/lib/grape/dsl/settings.rb +1 -1
- data/lib/grape/dsl/version_options.rb +2 -2
- data/lib/grape/dsl/versioning.rb +98 -0
- data/lib/grape/endpoint/state.rb +15 -0
- data/lib/grape/endpoint.rb +229 -137
- data/lib/grape/error_formatter/base.rb +28 -13
- data/lib/grape/error_formatter/json.rb +3 -0
- data/lib/grape/error_formatter/jsonl.rb +15 -0
- data/lib/grape/error_formatter/xml.rb +3 -1
- data/lib/grape/exceptions/error_response.rb +23 -7
- data/lib/grape/exceptions/halt.rb +39 -0
- data/lib/grape/exceptions/validation.rb +9 -9
- data/lib/grape/exceptions/validation_errors.rb +12 -2
- data/lib/grape/formatter/jsonl.rb +34 -0
- data/lib/grape/formatter/markdown.rb +17 -0
- data/lib/grape/formatter/md.rb +11 -0
- data/lib/grape/locale/en.yml +1 -0
- data/lib/grape/middleware/auth/base.rb +16 -1
- data/lib/grape/middleware/auth/strategy_info.rb +2 -2
- data/lib/grape/middleware/base.rb +19 -13
- data/lib/grape/middleware/error.rb +133 -35
- data/lib/grape/middleware/formatter.rb +235 -94
- data/lib/grape/middleware/precomputed_content_types.rb +14 -2
- data/lib/grape/middleware/stack.rb +7 -8
- data/lib/grape/middleware/versioner/base.rb +26 -10
- data/lib/grape/middleware/versioner/header.rb +70 -15
- data/lib/grape/middleware/versioner/param.rb +3 -5
- data/lib/grape/middleware/versioner/path.rb +20 -11
- data/lib/grape/middleware/versioner.rb +1 -1
- data/lib/grape/mountable.rb +2 -4
- data/lib/grape/namespace.rb +2 -3
- data/lib/grape/parser/jsonl.rb +19 -0
- data/lib/grape/request.rb +46 -8
- data/lib/grape/router/base_route.rb +41 -0
- data/lib/grape/router/greedy_route.rb +1 -1
- data/lib/grape/router/mustermann_pattern.rb +1 -1
- data/lib/grape/router/pattern/path.rb +1 -1
- data/lib/grape/router/pattern.rb +11 -5
- data/lib/grape/router/route.rb +42 -11
- data/lib/grape/router/route_buckets.rb +246 -0
- data/lib/grape/router.rb +262 -32
- data/lib/grape/util/endpoint_configuration.rb +7 -1
- data/lib/grape/util/inheritable_setting.rb +80 -161
- data/lib/grape/util/lazy/value.rb +52 -11
- data/lib/grape/util/media_type.rb +38 -15
- data/lib/grape/util/path_normalizer.rb +7 -2
- data/lib/grape/util/registry.rb +9 -2
- data/lib/grape/util/scrub.rb +33 -0
- data/lib/grape/util/translation.rb +6 -6
- data/lib/grape/validations/attributes_iterator.rb +73 -37
- data/lib/grape/validations/coerce_options.rb +1 -1
- data/lib/grape/validations/params_documentation.rb +15 -7
- data/lib/grape/validations/params_scope.rb +176 -43
- data/lib/grape/validations/types/custom_type_coercer.rb +2 -3
- data/lib/grape/validations/types/custom_type_collection_coercer.rb +1 -1
- data/lib/grape/validations/types/dry_type_coercer.rb +20 -12
- data/lib/grape/validations/types/multiple_type_coercer.rb +1 -2
- data/lib/grape/validations/types/primitive_coercer.rb +17 -0
- data/lib/grape/validations/types/variant_collection_coercer.rb +24 -10
- data/lib/grape/validations/types.rb +12 -18
- data/lib/grape/validations/validations_spec.rb +53 -22
- data/lib/grape/validations/validators/allow_blank_validator.rb +2 -2
- data/lib/grape/validations/validators/as_validator.rb +2 -3
- data/lib/grape/validations/validators/base.rb +124 -25
- data/lib/grape/validations/validators/coerce_validator.rb +2 -3
- data/lib/grape/validations/validators/default_validator.rb +18 -2
- data/lib/grape/validations/validators/except_values_validator.rb +16 -3
- data/lib/grape/validations/validators/hash_elements_validator.rb +34 -0
- data/lib/grape/validations/validators/length_validator.rb +24 -16
- data/lib/grape/validations/validators/multiple_params_base.rb +0 -4
- data/lib/grape/validations/validators/values_validator.rb +18 -24
- data/lib/grape/version.rb +1 -2
- data/lib/grape.rb +3 -0
- metadata +18 -11
- data/lib/grape/util/lazy/value_array.rb +0 -21
- data/lib/grape/util/lazy/value_enumerable.rb +0 -31
- data/lib/grape/util/lazy/value_hash.rb +0 -21
- data/lib/grape/validations/multiple_attributes_iterator.rb +0 -13
- data/lib/grape/validations/single_attribute_iterator.rb +0 -28
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 123b3c7cb9a7f529aa206d3523a2694dd0ee0ed831add48498e76bb5eb9e69c6
|
|
4
|
+
data.tar.gz: dc6d8f9f54404a572540a796483c1d2a94e38b49ec663f8b411a37dbb7b94fbc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9d2382c6f5f51ce1c44ad64c9b88f623ce8223ded9f79fc45a350520be33b626fa8f9b819a0b7a89d5f9d513e5b0170c875c7eccaad605802d529920dcc0a1ea
|
|
7
|
+
data.tar.gz: 530e1f0736f8cfed885af1d20aa0c53af939262299baa791cebe01555d9514633f59950229899a5bf83fb0e67869e07d112f1427cf1ef87c198853685a95a27d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,111 @@
|
|
|
1
|
+
### 4.1.0 (2026-10-31)
|
|
2
|
+
|
|
3
|
+
#### Features
|
|
4
|
+
|
|
5
|
+
* [#2914](https://github.com/ruby-grape/grape/pull/2914): Bench 4.0.0 in the version throughput benchmark - [@ericproulx](https://github.com/ericproulx).
|
|
6
|
+
* [#2913](https://github.com/ruby-grape/grape/pull/2913): Bench ZJIT alongside YJIT in the version benchmark - [@ericproulx](https://github.com/ericproulx).
|
|
7
|
+
* [#2941](https://github.com/ruby-grape/grape/pull/2941): Bench static, parameterized and many-route shapes in separate tables in the version throughput benchmark - [@ericproulx](https://github.com/ericproulx).
|
|
8
|
+
* [#2951](https://github.com/ruby-grape/grape/pull/2951): Re-bench only `master` in the version throughput benchmark and carry released versions' results over - [@ericproulx](https://github.com/ericproulx).
|
|
9
|
+
* [#2960](https://github.com/ruby-grape/grape/pull/2960): Lint every response of an API once under `lint!`, including the router's 404 and mounted Rack apps, instead of inside each endpoint's stack - [@ericproulx](https://github.com/ericproulx).
|
|
10
|
+
* [#2966](https://github.com/ruby-grape/grape/pull/2966): Require Ruby 3.3.1, the first 3.3 release that parses anonymous argument forwarding from inside a block - [@ericproulx](https://github.com/ericproulx).
|
|
11
|
+
* [#3008](https://github.com/ruby-grape/grape/pull/3008): Add the grape-on-rack app as a live-server memory profiling harness - [@ericproulx](https://github.com/ericproulx).
|
|
12
|
+
* [#3025](https://github.com/ruby-grape/grape/pull/3025): Add `:md` and `:markdown` formatters that render an object's `to_markdown`, for APIs that declare a `text/markdown` content type - [@ericproulx](https://github.com/ericproulx).
|
|
13
|
+
* [#3029](https://github.com/ruby-grape/grape/pull/3029): Add a built-in `:jsonl` (JSON Lines) format that streams an Enumerator body - [@ericproulx](https://github.com/ericproulx).
|
|
14
|
+
* [#3040](https://github.com/ruby-grape/grape/pull/3040): Add the `raise_rescue_handler_errors` setting to let an exception raised inside a `rescue_from` block propagate - [@dduugg](https://github.com/dduugg).
|
|
15
|
+
|
|
16
|
+
#### Fixes
|
|
17
|
+
|
|
18
|
+
* [#2916](https://github.com/ruby-grape/grape/pull/2916): Pin `json` below 3 in the gemfiles whose dependencies cannot use it - [@ericproulx](https://github.com/ericproulx).
|
|
19
|
+
* [#2915](https://github.com/ruby-grape/grape/pull/2915): Update rubocop to 1.90.0 and rubocop-performance to 1.27.0 - [@ericproulx](https://github.com/ericproulx).
|
|
20
|
+
* [#2918](https://github.com/ruby-grape/grape/pull/2918): Skip the dry-types round trip when a value already is the declared type - [@ericproulx](https://github.com/ericproulx).
|
|
21
|
+
* [#2917](https://github.com/ruby-grape/grape/pull/2917): Read path captures out of the router's union match instead of re-running the route's pattern - [@ericproulx](https://github.com/ericproulx).
|
|
22
|
+
* [#2921](https://github.com/ruby-grape/grape/pull/2921): Pin the router's request-time isolation regressions through requests instead of its instance variables - [@ericproulx](https://github.com/ericproulx).
|
|
23
|
+
* [#2935](https://github.com/ruby-grape/grape/pull/2935): Return the elements of an Array params scope that are not a Hash from `declared` instead of raising - [@ericproulx](https://github.com/ericproulx).
|
|
24
|
+
* [#2937](https://github.com/ruby-grape/grape/pull/2937): Forward the class methods kept off an API class to its base instance explicitly, and pin what `delegate_missing_to` still answers - [@ericproulx](https://github.com/ericproulx).
|
|
25
|
+
* [#2936](https://github.com/ruby-grape/grape/pull/2936): Speed up header versioning, content negotiation, params validation and error responses on the request path - [@ericproulx](https://github.com/ericproulx).
|
|
26
|
+
* [#2938](https://github.com/ruby-grape/grape/pull/2938): Correct code comments that no longer match the code - [@ericproulx](https://github.com/ericproulx).
|
|
27
|
+
* [#2939](https://github.com/ruby-grape/grape/pull/2939): Speed up error responses, param defaults and deciding whether to read a request body - [@ericproulx](https://github.com/ericproulx).
|
|
28
|
+
* [#2940](https://github.com/ruby-grape/grape/pull/2940): Speed up matching fully static routes - [@ericproulx](https://github.com/ericproulx).
|
|
29
|
+
* [#2942](https://github.com/ruby-grape/grape/pull/2942): Route a path carrying raw non-ASCII bytes on an API with a non-ASCII route instead of raising `Encoding::CompatibilityError` - [@ericproulx](https://github.com/ericproulx).
|
|
30
|
+
* [#2920](https://github.com/ruby-grape/grape/pull/2920): Look for a 405 neighbour only on paths the request's method has no route on - [@ericproulx](https://github.com/ericproulx).
|
|
31
|
+
* [#2943](https://github.com/ruby-grape/grape/pull/2943): Speed up matching among many parameterized routes - [@ericproulx](https://github.com/ericproulx).
|
|
32
|
+
* [#2948](https://github.com/ruby-grape/grape/pull/2948): Speed up path-versioned requests and error responses - [@ericproulx](https://github.com/ericproulx).
|
|
33
|
+
* [#2949](https://github.com/ruby-grape/grape/pull/2949): Present an error response with the entity a `desc` `failure:` keyword names - [@ericproulx](https://github.com/ericproulx).
|
|
34
|
+
* [#2947](https://github.com/ruby-grape/grape/pull/2947): Speed up `declared` filling in a missing Hash param - [@ericproulx](https://github.com/ericproulx).
|
|
35
|
+
* [#2950](https://github.com/ruby-grape/grape/pull/2950): Read a configuration key nested in a Hash or an Array in a remountable API instead of raising `NoMethodError` - [@ericproulx](https://github.com/ericproulx).
|
|
36
|
+
* [#2952](https://github.com/ruby-grape/grape/pull/2952): Route a path running on from the segment ahead of a trailing `*path` the same way on an API with many routes as on one with few - [@ericproulx](https://github.com/ericproulx).
|
|
37
|
+
* [#2954](https://github.com/ruby-grape/grape/pull/2954): Answer a `DELETE` whose body holds bytes invalid in its encoding with `200` instead of raising `ArgumentError` - [@ericproulx](https://github.com/ericproulx).
|
|
38
|
+
* [#2956](https://github.com/ruby-grape/grape/pull/2956): Keep every mount of an API mounted more than once when a later declaration refreshes the mounts - [@ericproulx](https://github.com/ericproulx).
|
|
39
|
+
* [#2958](https://github.com/ruby-grape/grape/pull/2958): Answer a `HEAD` request for a path no route matches without a body - [@ericproulx](https://github.com/ericproulx).
|
|
40
|
+
* [#2953](https://github.com/ruby-grape/grape/pull/2953): Answer an `error!` String message with its own status instead of a `500` when the route names a `failure` entity for that status - [@ericproulx](https://github.com/ericproulx).
|
|
41
|
+
* [#2955](https://github.com/ruby-grape/grape/pull/2955): Reject a value that is not an Array, and a member of none of the types, in a collection with multiple member types instead of passing them on as `nil` and `InvalidValue` - [@ericproulx](https://github.com/ericproulx).
|
|
42
|
+
* [#2957](https://github.com/ruby-grape/grape/pull/2957): Reject an element that is not a Hash in an Array param given a block, and stop `declared` raising on a value that is not a Hash where nested params are declared - [@ericproulx](https://github.com/ericproulx).
|
|
43
|
+
* [#2959](https://github.com/ruby-grape/grape/pull/2959): Send a content type for an `api_format` the API does not declare instead of a `nil` header - [@ericproulx](https://github.com/ericproulx).
|
|
44
|
+
* [#2961](https://github.com/ruby-grape/grape/pull/2961): Correct the README on where `using: :param` reads the version from and on the status of an unsupported request content type - [@ericproulx](https://github.com/ericproulx).
|
|
45
|
+
* [#2963](https://github.com/ruby-grape/grape/pull/2963): Stop reading a setting on an API class, such as `MyAPI.version`, from discarding the compiled API and re-mounting everything mounted in it - [@ericproulx](https://github.com/ericproulx).
|
|
46
|
+
* [#2964](https://github.com/ruby-grape/grape/pull/2964): Stop keeping every instance a mounted API was re-mounted with each time a later declaration refreshed the mounts - [@ericproulx](https://github.com/ericproulx).
|
|
47
|
+
* [#2965](https://github.com/ruby-grape/grape/pull/2965): Correct two README examples whose shown response did not match their request - [@ericproulx](https://github.com/ericproulx).
|
|
48
|
+
* [#2967](https://github.com/ruby-grape/grape/pull/2967): Hand a Proc passed as the last argument to `use`, `insert_before` or `insert_after` to the middleware instead of taking it for its block - [@ericproulx](https://github.com/ericproulx).
|
|
49
|
+
* [#2968](https://github.com/ruby-grape/grape/pull/2968): Label a `redirect` body the caller supplies with the API format it is rendered in instead of `text/plain` - [@ericproulx](https://github.com/ericproulx).
|
|
50
|
+
* [#2972](https://github.com/ruby-grape/grape/pull/2972): Stop the request path resolving params it was not asked for - [@ericproulx](https://github.com/ericproulx).
|
|
51
|
+
* [#2973](https://github.com/ruby-grape/grape/pull/2973): Stop allocating two match caches per route that Mustermann is never asked to use - [@ericproulx](https://github.com/ericproulx).
|
|
52
|
+
* [#2977](https://github.com/ruby-grape/grape/pull/2977): Stop copying the query params of a request whose params builder builds a new object - [@ericproulx](https://github.com/ericproulx).
|
|
53
|
+
* [#2974](https://github.com/ruby-grape/grape/pull/2974): Run every endpoint's Rack stack through one shared lambda instead of one allocated per endpoint, and make `Grape::Endpoint#run` public - [@ericproulx](https://github.com/ericproulx).
|
|
54
|
+
* [#2975](https://github.com/ruby-grape/grape/pull/2975): Hold a static `values` or `except_values` collection as it came instead of behind a lambda that only hands it back - [@ericproulx](https://github.com/ericproulx).
|
|
55
|
+
* [#2976](https://github.com/ruby-grape/grape/pull/2976): Replace a registry on registration instead of writing into it, so a registered formatter, parser, params builder, validator or versioner cannot be changed underneath a reader - [@ericproulx](https://github.com/ericproulx).
|
|
56
|
+
* [#2982](https://github.com/ruby-grape/grape/pull/2982): Check `Boolean` values directly instead of through `Grape::API::Boolean.build` - [@ericproulx](https://github.com/ericproulx).
|
|
57
|
+
* [#2986](https://github.com/ruby-grape/grape/pull/2986): Match a header-versioned vendor declared with capitals - [@ericproulx](https://github.com/ericproulx).
|
|
58
|
+
* [#2987](https://github.com/ruby-grape/grape/pull/2987): Match a header version or content type declared with capitals - [@ericproulx](https://github.com/ericproulx).
|
|
59
|
+
* [#2988](https://github.com/ruby-grape/grape/pull/2988): Drop the routed-version check left behind in `Versioner::Path#before` - [@ericproulx](https://github.com/ericproulx).
|
|
60
|
+
* [#2989](https://github.com/ruby-grape/grape/pull/2989): Leave the API format untouched when `format` rejects one with no content type - [@ericproulx](https://github.com/ericproulx).
|
|
61
|
+
* [#2990](https://github.com/ruby-grape/grape/pull/2990): Name a nested array element by its own indices when a Hash scope sits between two Array scopes - [@ericproulx](https://github.com/ericproulx).
|
|
62
|
+
* [#2991](https://github.com/ruby-grape/grape/pull/2991): Require exactly one name for a `requires` or `optional` block - [@ericproulx](https://github.com/ericproulx).
|
|
63
|
+
* [#2992](https://github.com/ruby-grape/grape/pull/2992): Accept a beginless range of `values` for a bare `Array` type - [@ericproulx](https://github.com/ericproulx).
|
|
64
|
+
* [#2993](https://github.com/ruby-grape/grape/pull/2993): Say a param is invalid when its validation error has no message, instead of naming the exception class - [@ericproulx](https://github.com/ericproulx).
|
|
65
|
+
* [#2994](https://github.com/ruby-grape/grape/pull/2994): Honour the message of a `coerce:` option given as `{ value:, message: }` - [@ericproulx](https://github.com/ericproulx).
|
|
66
|
+
* [#2995](https://github.com/ruby-grape/grape/pull/2995): Merge a middleware's headers with a guard clause instead of a `case` - [@ericproulx](https://github.com/ericproulx).
|
|
67
|
+
* [#2996](https://github.com/ruby-grape/grape/pull/2996): Cover the header versioner's last two branches - [@ericproulx](https://github.com/ericproulx).
|
|
68
|
+
* [#2997](https://github.com/ruby-grape/grape/pull/2997): Cover the router's missed branches and drop its dead guards - [@ericproulx](https://github.com/ericproulx).
|
|
69
|
+
* [#2998](https://github.com/ruby-grape/grape/pull/2998): Drop the unused `simplecov-lcov` setup; Coveralls reads SimpleCov's own results - [@ericproulx](https://github.com/ericproulx).
|
|
70
|
+
* [#3001](https://github.com/ruby-grape/grape/pull/3001): Drop the safe navigation on the declared handler's contract key maps - [@ericproulx](https://github.com/ericproulx).
|
|
71
|
+
* [#3002](https://github.com/ruby-grape/grape/pull/3002): Render an XML error without checking for `to_xml` - [@ericproulx](https://github.com/ericproulx).
|
|
72
|
+
* [#3004](https://github.com/ruby-grape/grape/pull/3004): Stop copying the formatter and calling empty filter phases per request - [@ericproulx](https://github.com/ericproulx).
|
|
73
|
+
* [#3005](https://github.com/ruby-grape/grape/pull/3005): Load rails before grape in the Rails gemfiles so the specs exercise loading `Grape::Railtie` - [@ericproulx](https://github.com/ericproulx).
|
|
74
|
+
* [#3006](https://github.com/ruby-grape/grape/pull/3006): Answer params and versions holding invalid bytes instead of raising `ArgumentError` - [@ericproulx](https://github.com/ericproulx).
|
|
75
|
+
* [#3007](https://github.com/ruby-grape/grape/pull/3007): Reserve `blank?` and `present?` for outside input and check Grape's own values precisely - [@ericproulx](https://github.com/ericproulx).
|
|
76
|
+
* [#3009](https://github.com/ruby-grape/grape/pull/3009): Fold `SingleAttributeIterator` and `MultipleAttributesIterator` into `AttributesIterator` - [@ericproulx](https://github.com/ericproulx).
|
|
77
|
+
* [#3010](https://github.com/ruby-grape/grape/pull/3010): Reject `nil` for a required param with `values` in a nested scope, as the root scope does - [@ericproulx](https://github.com/ericproulx).
|
|
78
|
+
* [#3011](https://github.com/ruby-grape/grape/pull/3011): Reject a number with a fractional part for an `Integer` param instead of truncating it - [@ericproulx](https://github.com/ericproulx).
|
|
79
|
+
* [#3012](https://github.com/ruby-grape/grape/pull/3012): Route a mounted Rack app as an ANY route in the order it was mounted - [@ericproulx](https://github.com/ericproulx).
|
|
80
|
+
* [#3013](https://github.com/ruby-grape/grape/pull/3013): Read a header version holding a hyphen, such as `2024-06-20`, whole - [@ericproulx](https://github.com/ericproulx).
|
|
81
|
+
* [#3014](https://github.com/ruby-grape/grape/pull/3014): Validate a blank element of an optional Array block when other elements are not blank - [@ericproulx](https://github.com/ericproulx).
|
|
82
|
+
* [#3015](https://github.com/ruby-grape/grape/pull/3015): Answer in the default format when a negotiated format cannot render the body, instead of 500 - [@ericproulx](https://github.com/ericproulx).
|
|
83
|
+
* [#3016](https://github.com/ruby-grape/grape/pull/3016): Stop copying the error middleware on requests that do not fail - [@ericproulx](https://github.com/ericproulx).
|
|
84
|
+
* [#3017](https://github.com/ruby-grape/grape/pull/3017): Stop copying the header versioner per request for an Accept header it answers from its table - [@ericproulx](https://github.com/ericproulx).
|
|
85
|
+
* [#3018](https://github.com/ruby-grape/grape/pull/3018): Stop copying the auth middleware per request - [@ericproulx](https://github.com/ericproulx).
|
|
86
|
+
* [#3023](https://github.com/ruby-grape/grape/pull/3023): Raise from `error!` instead of throwing `:error`, so a transaction it leaves rolls back - [@ericproulx](https://github.com/ericproulx).
|
|
87
|
+
* [#3024](https://github.com/ruby-grape/grape/pull/3024): Keep a logger set on one API from replacing every other API's - [@ericproulx](https://github.com/ericproulx).
|
|
88
|
+
* [#3026](https://github.com/ruby-grape/grape/pull/3026): Answer `cascade` false from the reader for a version declared with `cascade: false` - [@ericproulx](https://github.com/ericproulx).
|
|
89
|
+
* [#3027](https://github.com/ruby-grape/grape/pull/3027): Scrub outside input through one helper, `Grape::Util::Scrub` - [@ericproulx](https://github.com/ericproulx).
|
|
90
|
+
* [#3028](https://github.com/ruby-grape/grape/pull/3028): Resolve a scope's request params in `ParamsScope` instead of the params DSL - [@ericproulx](https://github.com/ericproulx).
|
|
91
|
+
* [#3030](https://github.com/ruby-grape/grape/pull/3030): Restore the Error middleware's two defaults without restating every option - [@ericproulx](https://github.com/ericproulx).
|
|
92
|
+
* [#3035](https://github.com/ruby-grape/grape/pull/3035): Define `requires` and `optional` from one definition - [@ericproulx](https://github.com/ericproulx).
|
|
93
|
+
* [#3036](https://github.com/ruby-grape/grape/pull/3036): Hold every method to RuboCop's default cyclomatic complexity - [@ericproulx](https://github.com/ericproulx).
|
|
94
|
+
* [#3037](https://github.com/ruby-grape/grape/pull/3037): Hold every method to RuboCop's default perceived complexity - [@ericproulx](https://github.com/ericproulx).
|
|
95
|
+
* [#3033](https://github.com/ruby-grape/grape/pull/3033): Allocate less per request when presenting an entity or reading path params - [@ericproulx](https://github.com/ericproulx).
|
|
96
|
+
* [#3034](https://github.com/ruby-grape/grape/pull/3034): Shrink each request's copy of its endpoint - [@ericproulx](https://github.com/ericproulx).
|
|
97
|
+
* [#3038](https://github.com/ruby-grape/grape/pull/3038): Hold every method to RuboCop's default ABC size - [@ericproulx](https://github.com/ericproulx).
|
|
98
|
+
* [#3039](https://github.com/ruby-grape/grape/pull/3039): Hold every module to RuboCop's default length - [@ericproulx](https://github.com/ericproulx).
|
|
99
|
+
* [#3031](https://github.com/ruby-grape/grape/pull/3031): Define `InheritableSetting`'s scalar settings and scope flags by key - [@ericproulx](https://github.com/ericproulx).
|
|
100
|
+
* [#3032](https://github.com/ruby-grape/grape/pull/3032): Keep each API's content type order when negotiating a browser's `*/*` - [@ericproulx](https://github.com/ericproulx).
|
|
101
|
+
* [#3042](https://github.com/ruby-grape/grape/pull/3042): Answer `HEAD` without a body from a mounted Rack app by wrapping the router in `Rack::Head` - [@ericproulx](https://github.com/ericproulx).
|
|
102
|
+
|
|
103
|
+
### 4.0.1 (2026-09-15)
|
|
104
|
+
|
|
105
|
+
#### Fixes
|
|
106
|
+
|
|
107
|
+
* [#2946](https://github.com/ruby-grape/grape/pull/2946): Stop reading a class-level setting on an API with nested mounts from remounting the whole mount tree - [@ericproulx](https://github.com/ericproulx).
|
|
108
|
+
|
|
1
109
|
### 4.0.0 (2026-09-07)
|
|
2
110
|
|
|
3
111
|
#### Features
|
|
@@ -1509,4 +1617,3 @@
|
|
|
1509
1617
|
### 0.1.0 (2010/11/13)
|
|
1510
1618
|
|
|
1511
1619
|
* Initial public release - [@mbleigh](https://github.com/mbleigh).
|
|
1512
|
-
|