grape 2.0.0 → 2.4.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 +151 -1
- data/CONTRIBUTING.md +1 -1
- data/README.md +404 -334
- data/UPGRADING.md +279 -7
- data/grape.gemspec +8 -8
- data/lib/grape/api/instance.rb +34 -66
- data/lib/grape/api.rb +47 -70
- data/lib/grape/content_types.rb +13 -10
- data/lib/grape/cookies.rb +31 -24
- data/lib/grape/dry_types.rb +0 -2
- data/lib/grape/dsl/api.rb +0 -2
- data/lib/grape/dsl/desc.rb +49 -44
- data/lib/grape/dsl/headers.rb +2 -2
- data/lib/grape/dsl/helpers.rb +8 -4
- data/lib/grape/dsl/inside_route.rb +67 -54
- data/lib/grape/dsl/parameters.rb +10 -9
- data/lib/grape/dsl/request_response.rb +14 -18
- data/lib/grape/dsl/routing.rb +34 -17
- data/lib/grape/dsl/validations.rb +13 -0
- data/lib/grape/endpoint.rb +120 -118
- data/lib/grape/{util/env.rb → env.rb} +0 -5
- data/lib/grape/error_formatter/base.rb +51 -21
- data/lib/grape/error_formatter/json.rb +7 -15
- data/lib/grape/error_formatter/serializable_hash.rb +7 -0
- data/lib/grape/error_formatter/txt.rb +11 -17
- data/lib/grape/error_formatter/xml.rb +3 -13
- data/lib/grape/error_formatter.rb +5 -25
- data/lib/grape/exceptions/base.rb +18 -30
- data/lib/grape/exceptions/conflicting_types.rb +11 -0
- data/lib/grape/exceptions/invalid_parameters.rb +11 -0
- data/lib/grape/exceptions/too_deep_parameters.rb +11 -0
- data/lib/grape/exceptions/unknown_auth_strategy.rb +11 -0
- data/lib/grape/exceptions/unknown_params_builder.rb +11 -0
- data/lib/grape/exceptions/validation.rb +5 -6
- data/lib/grape/exceptions/validation_array_errors.rb +1 -0
- data/lib/grape/exceptions/validation_errors.rb +4 -6
- data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +2 -5
- data/lib/grape/extensions/hash.rb +7 -2
- data/lib/grape/extensions/hashie/mash.rb +3 -5
- data/lib/grape/formatter/base.rb +16 -0
- data/lib/grape/formatter/json.rb +4 -6
- data/lib/grape/formatter/serializable_hash.rb +1 -1
- data/lib/grape/formatter/txt.rb +3 -5
- data/lib/grape/formatter/xml.rb +4 -6
- data/lib/grape/formatter.rb +7 -25
- data/lib/grape/{util/json.rb → json.rb} +1 -3
- data/lib/grape/locale/en.yml +46 -42
- data/lib/grape/middleware/auth/base.rb +11 -34
- data/lib/grape/middleware/auth/dsl.rb +23 -31
- data/lib/grape/middleware/base.rb +41 -23
- data/lib/grape/middleware/error.rb +77 -76
- data/lib/grape/middleware/formatter.rb +48 -79
- data/lib/grape/middleware/globals.rb +1 -3
- data/lib/grape/middleware/stack.rb +26 -37
- data/lib/grape/middleware/versioner/accept_version_header.rb +6 -33
- data/lib/grape/middleware/versioner/base.rb +74 -0
- data/lib/grape/middleware/versioner/header.rb +59 -126
- data/lib/grape/middleware/versioner/param.rb +4 -25
- data/lib/grape/middleware/versioner/path.rb +10 -34
- data/lib/grape/middleware/versioner.rb +7 -14
- data/lib/grape/namespace.rb +4 -5
- data/lib/grape/params_builder/base.rb +18 -0
- data/lib/grape/params_builder/hash.rb +11 -0
- data/lib/grape/params_builder/hash_with_indifferent_access.rb +11 -0
- data/lib/grape/params_builder/hashie_mash.rb +11 -0
- data/lib/grape/params_builder.rb +32 -0
- data/lib/grape/parser/base.rb +16 -0
- data/lib/grape/parser/json.rb +6 -8
- data/lib/grape/parser/xml.rb +6 -8
- data/lib/grape/parser.rb +5 -23
- data/lib/grape/path.rb +38 -60
- data/lib/grape/request.rb +161 -30
- data/lib/grape/router/base_route.rb +39 -0
- data/lib/grape/router/greedy_route.rb +20 -0
- data/lib/grape/router/pattern.rb +45 -31
- data/lib/grape/router/route.rb +28 -57
- data/lib/grape/router.rb +56 -43
- data/lib/grape/util/base_inheritable.rb +4 -4
- data/lib/grape/util/cache.rb +0 -3
- data/lib/grape/util/endpoint_configuration.rb +1 -1
- data/lib/grape/util/header.rb +13 -0
- data/lib/grape/util/inheritable_values.rb +0 -2
- data/lib/grape/util/lazy/block.rb +29 -0
- data/lib/grape/util/lazy/value.rb +38 -0
- data/lib/grape/util/lazy/value_array.rb +21 -0
- data/lib/grape/util/lazy/value_enumerable.rb +34 -0
- data/lib/grape/util/lazy/value_hash.rb +21 -0
- data/lib/grape/util/media_type.rb +70 -0
- data/lib/grape/util/registry.rb +27 -0
- data/lib/grape/util/reverse_stackable_values.rb +1 -6
- data/lib/grape/util/stackable_values.rb +1 -6
- data/lib/grape/util/strict_hash_configuration.rb +3 -3
- data/lib/grape/validations/attributes_doc.rb +38 -36
- data/lib/grape/validations/attributes_iterator.rb +1 -0
- data/lib/grape/validations/contract_scope.rb +34 -0
- data/lib/grape/validations/params_scope.rb +36 -32
- data/lib/grape/validations/types/array_coercer.rb +0 -2
- data/lib/grape/validations/types/dry_type_coercer.rb +9 -15
- data/lib/grape/validations/types/json.rb +0 -2
- data/lib/grape/validations/types/primitive_coercer.rb +0 -2
- data/lib/grape/validations/types/set_coercer.rb +0 -3
- data/lib/grape/validations/types.rb +0 -3
- data/lib/grape/validations/validator_factory.rb +2 -2
- data/lib/grape/validations/validators/allow_blank_validator.rb +1 -1
- data/lib/grape/validations/validators/base.rb +8 -11
- data/lib/grape/validations/validators/coerce_validator.rb +1 -1
- data/lib/grape/validations/validators/contract_scope_validator.rb +41 -0
- data/lib/grape/validations/validators/default_validator.rb +6 -2
- data/lib/grape/validations/validators/exactly_one_of_validator.rb +1 -1
- data/lib/grape/validations/validators/except_values_validator.rb +2 -2
- data/lib/grape/validations/validators/length_validator.rb +49 -0
- data/lib/grape/validations/validators/presence_validator.rb +1 -1
- data/lib/grape/validations/validators/regexp_validator.rb +2 -2
- data/lib/grape/validations/validators/values_validator.rb +20 -57
- data/lib/grape/validations.rb +8 -21
- data/lib/grape/version.rb +1 -1
- data/lib/grape/{util/xml.rb → xml.rb} +1 -1
- data/lib/grape.rb +42 -274
- metadata +45 -44
- data/lib/grape/eager_load.rb +0 -20
- data/lib/grape/http/headers.rb +0 -71
- data/lib/grape/middleware/helpers.rb +0 -12
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +0 -24
- data/lib/grape/router/attribute_translator.rb +0 -63
- data/lib/grape/util/lazy_block.rb +0 -27
- data/lib/grape/util/lazy_object.rb +0 -43
- data/lib/grape/util/lazy_value.rb +0 -91
- data/lib/grape/util/registrable.rb +0 -15
- data/lib/grape/validations/types/build_coercer.rb +0 -94
data/lib/grape/api.rb
CHANGED
@@ -1,14 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'grape/router'
|
4
|
-
require 'grape/api/instance'
|
5
|
-
|
6
3
|
module Grape
|
7
4
|
# The API class is the primary entry point for creating Grape APIs. Users
|
8
5
|
# should subclass this class in order to build an API.
|
9
6
|
class API
|
10
7
|
# Class methods that we want to call on the API rather than on the API object
|
11
|
-
NON_OVERRIDABLE = %i[call call! configuration compile! inherited].freeze
|
8
|
+
NON_OVERRIDABLE = %i[call call! configuration compile! inherited recognize_path].freeze
|
12
9
|
|
13
10
|
class Boolean
|
14
11
|
def self.build(val)
|
@@ -23,19 +20,25 @@ module Grape
|
|
23
20
|
end
|
24
21
|
|
25
22
|
class << self
|
23
|
+
extend Forwardable
|
26
24
|
attr_accessor :base_instance, :instances
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
delegate_missing_to :base_instance
|
27
|
+
def_delegators :base_instance, :new, :configuration
|
28
|
+
|
29
|
+
# This is the interface point between Rack and Grape; it accepts a request
|
30
|
+
# from Rack and ultimately returns an array of three values: the status,
|
31
|
+
# the headers, and the body. See [the rack specification]
|
32
|
+
# (http://www.rubydoc.info/github/rack/rack/master/file/SPEC) for more.
|
33
|
+
# NOTE: This will only be called on an API directly mounted on RACK
|
34
|
+
def_delegators :instance_for_rack, :call, :compile!
|
32
35
|
|
33
36
|
# When inherited, will create a list of all instances (times the API was mounted)
|
34
37
|
# It will listen to the setup required to mount that endpoint, and replicate it on any new instance
|
35
38
|
def inherited(api)
|
36
39
|
super
|
37
40
|
|
38
|
-
api.initial_setup(Grape::API
|
41
|
+
api.initial_setup(self == Grape::API ? Grape::API::Instance : @base_instance)
|
39
42
|
api.override_all_methods!
|
40
43
|
end
|
41
44
|
|
@@ -43,7 +46,7 @@ module Grape
|
|
43
46
|
# an instance that will be used to create the set up but will not be mounted
|
44
47
|
def initial_setup(base_instance_parent)
|
45
48
|
@instances = []
|
46
|
-
@setup =
|
49
|
+
@setup = []
|
47
50
|
@base_parent = base_instance_parent
|
48
51
|
@base_instance = mount_instance
|
49
52
|
end
|
@@ -52,7 +55,7 @@ module Grape
|
|
52
55
|
def override_all_methods!
|
53
56
|
(base_instance.methods - Class.methods - NON_OVERRIDABLE).each do |method_override|
|
54
57
|
define_singleton_method(method_override) do |*args, &block|
|
55
|
-
add_setup(method_override,
|
58
|
+
add_setup(method: method_override, args: args, block: block)
|
56
59
|
end
|
57
60
|
end
|
58
61
|
end
|
@@ -72,68 +75,28 @@ module Grape
|
|
72
75
|
end
|
73
76
|
end
|
74
77
|
|
75
|
-
# This is the interface point between Rack and Grape; it accepts a request
|
76
|
-
# from Rack and ultimately returns an array of three values: the status,
|
77
|
-
# the headers, and the body. See [the rack specification]
|
78
|
-
# (http://www.rubydoc.info/github/rack/rack/master/file/SPEC) for more.
|
79
|
-
# NOTE: This will only be called on an API directly mounted on RACK
|
80
|
-
def call(*args, &block)
|
81
|
-
instance_for_rack.call(*args, &block)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Alleviates problems with autoloading by tring to search for the constant
|
85
|
-
def const_missing(*args)
|
86
|
-
if base_instance.const_defined?(*args)
|
87
|
-
base_instance.const_get(*args)
|
88
|
-
else
|
89
|
-
super
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
78
|
# The remountable class can have a configuration hash to provide some dynamic class-level variables.
|
94
79
|
# For instance, a description could be done using: `desc configuration[:description]` if it may vary
|
95
80
|
# depending on where the endpoint is mounted. Use with care, if you find yourself using configuration
|
96
81
|
# too much, you may actually want to provide a new API rather than remount it.
|
97
|
-
def mount_instance(
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
82
|
+
def mount_instance(configuration: nil)
|
83
|
+
Class.new(@base_parent).tap do |instance|
|
84
|
+
instance.configuration = Grape::Util::EndpointConfiguration.new(configuration || {})
|
85
|
+
instance.base = self
|
86
|
+
replay_setup_on(instance)
|
87
|
+
end
|
103
88
|
end
|
104
89
|
|
90
|
+
private
|
91
|
+
|
105
92
|
# Replays the set up to produce an API as defined in this class, can be called
|
106
93
|
# on classes that inherit from Grape::API
|
107
94
|
def replay_setup_on(instance)
|
108
95
|
@setup.each do |setup_step|
|
109
|
-
replay_step_on(instance, setup_step)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def respond_to?(method, include_private = false)
|
114
|
-
super(method, include_private) || base_instance.respond_to?(method, include_private)
|
115
|
-
end
|
116
|
-
|
117
|
-
def respond_to_missing?(method, include_private = false)
|
118
|
-
base_instance.respond_to?(method, include_private)
|
119
|
-
end
|
120
|
-
|
121
|
-
def method_missing(method, *args, &block)
|
122
|
-
# If there's a missing method, it may be defined on the base_instance instead.
|
123
|
-
if respond_to_missing?(method)
|
124
|
-
base_instance.send(method, *args, &block)
|
125
|
-
else
|
126
|
-
super
|
96
|
+
replay_step_on(instance, **setup_step)
|
127
97
|
end
|
128
98
|
end
|
129
99
|
|
130
|
-
def compile!
|
131
|
-
require 'grape/eager_load'
|
132
|
-
instance_for_rack.compile! # See API::Instance.compile!
|
133
|
-
end
|
134
|
-
|
135
|
-
private
|
136
|
-
|
137
100
|
def instance_for_rack
|
138
101
|
if never_mounted?
|
139
102
|
base_instance
|
@@ -143,21 +106,35 @@ module Grape
|
|
143
106
|
end
|
144
107
|
|
145
108
|
# Adds a new stage to the set up require to get a Grape::API up and running
|
146
|
-
def add_setup(
|
147
|
-
|
148
|
-
@setup += [setup_step]
|
109
|
+
def add_setup(step)
|
110
|
+
@setup << step
|
149
111
|
last_response = nil
|
150
112
|
@instances.each do |instance|
|
151
|
-
last_response = replay_step_on(instance,
|
113
|
+
last_response = replay_step_on(instance, **step)
|
152
114
|
end
|
115
|
+
|
116
|
+
refresh_mount_step if step[:method] != :mount
|
153
117
|
last_response
|
154
118
|
end
|
155
119
|
|
156
|
-
|
157
|
-
|
120
|
+
# Updating all previously mounted classes in the case that new methods have been executed.
|
121
|
+
def refresh_mount_step
|
122
|
+
@setup.each do |setup_step|
|
123
|
+
next if setup_step[:method] != :mount
|
124
|
+
|
125
|
+
refresh_mount_step = setup_step.merge(method: :refresh_mounted_api)
|
126
|
+
@setup << refresh_mount_step
|
127
|
+
@instances.each do |instance|
|
128
|
+
replay_step_on(instance, **refresh_mount_step)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def replay_step_on(instance, method:, args:, block:)
|
134
|
+
return if skip_immediate_run?(instance, args)
|
158
135
|
|
159
|
-
|
160
|
-
response = instance.send(
|
136
|
+
eval_args = evaluate_arguments(instance.configuration, *args)
|
137
|
+
response = instance.send(method, *eval_args, &block)
|
161
138
|
if skip_immediate_run?(instance, [response])
|
162
139
|
response
|
163
140
|
else
|
@@ -172,12 +149,12 @@ module Grape
|
|
172
149
|
end
|
173
150
|
|
174
151
|
def any_lazy?(args)
|
175
|
-
args.any? { |argument| argument.
|
152
|
+
args.any? { |argument| argument.try(:lazy?) }
|
176
153
|
end
|
177
154
|
|
178
155
|
def evaluate_arguments(configuration, *args)
|
179
156
|
args.map do |argument|
|
180
|
-
if argument.
|
157
|
+
if argument.try(:lazy?)
|
181
158
|
argument.evaluate_from(configuration)
|
182
159
|
elsif argument.is_a?(Hash)
|
183
160
|
argument.transform_values { |value| evaluate_arguments(configuration, value).first }
|
data/lib/grape/content_types.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'grape/util/registrable'
|
4
|
-
|
5
3
|
module Grape
|
6
4
|
module ContentTypes
|
7
|
-
|
5
|
+
module_function
|
8
6
|
|
9
7
|
# Content types are listed in order of preference.
|
10
|
-
|
8
|
+
DEFAULTS = {
|
11
9
|
xml: 'application/xml',
|
12
10
|
serializable_hash: 'application/json',
|
13
11
|
json: 'application/json',
|
@@ -15,13 +13,18 @@ module Grape
|
|
15
13
|
txt: 'text/plain'
|
16
14
|
}.freeze
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
MIME_TYPES = Grape::ContentTypes::DEFAULTS.except(:serializable_hash).invert.freeze
|
17
|
+
|
18
|
+
def content_types_for(from_settings)
|
19
|
+
from_settings.presence || DEFAULTS
|
20
|
+
end
|
21
|
+
|
22
|
+
def mime_types_for(from_settings)
|
23
|
+
return MIME_TYPES if from_settings == Grape::ContentTypes::DEFAULTS
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
+
from_settings.each_with_object({}) do |(k, v), types_without_params|
|
26
|
+
# remove optional parameter
|
27
|
+
types_without_params[v.split(';', 2).first] = k
|
25
28
|
end
|
26
29
|
end
|
27
30
|
end
|
data/lib/grape/cookies.rb
CHANGED
@@ -2,42 +2,49 @@
|
|
2
2
|
|
3
3
|
module Grape
|
4
4
|
class Cookies
|
5
|
-
|
6
|
-
@cookies = {}
|
7
|
-
@send_cookies = {}
|
8
|
-
end
|
5
|
+
extend Forwardable
|
9
6
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
DELETED_COOKIES_ATTRS = {
|
8
|
+
max_age: '0',
|
9
|
+
value: '',
|
10
|
+
expires: Time.at(0)
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
def_delegators :cookies, :[], :each
|
14
|
+
|
15
|
+
def initialize(rack_cookies)
|
16
|
+
@cookies = rack_cookies
|
17
|
+
@send_cookies = nil
|
14
18
|
end
|
15
19
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
def response_cookies
|
21
|
+
return unless @send_cookies
|
22
|
+
|
23
|
+
send_cookies.each do |name|
|
24
|
+
yield name, cookies[name]
|
20
25
|
end
|
21
26
|
end
|
22
27
|
|
23
|
-
def [](name)
|
24
|
-
|
28
|
+
def []=(name, value)
|
29
|
+
cookies[name] = value
|
30
|
+
send_cookies << name
|
25
31
|
end
|
26
32
|
|
27
|
-
|
28
|
-
|
29
|
-
|
33
|
+
# see https://github.com/rack/rack/blob/main/lib/rack/utils.rb#L338-L340
|
34
|
+
def delete(name, **opts)
|
35
|
+
self.[]=(name, opts.merge(DELETED_COOKIES_ATTRS))
|
30
36
|
end
|
31
37
|
|
32
|
-
|
33
|
-
|
38
|
+
private
|
39
|
+
|
40
|
+
def cookies
|
41
|
+
return @cookies unless @cookies.is_a?(Proc)
|
42
|
+
|
43
|
+
@cookies = @cookies.call.with_indifferent_access
|
34
44
|
end
|
35
45
|
|
36
|
-
|
37
|
-
|
38
|
-
options = opts.merge(value: 'deleted', expires: Time.at(0))
|
39
|
-
self.[]=(name, options)
|
46
|
+
def send_cookies
|
47
|
+
@send_cookies ||= Set.new
|
40
48
|
end
|
41
|
-
# rubocop:enable Layout/SpaceBeforeBrackets
|
42
49
|
end
|
43
50
|
end
|
data/lib/grape/dry_types.rb
CHANGED
data/lib/grape/dsl/api.rb
CHANGED
data/lib/grape/dsl/desc.rb
CHANGED
@@ -5,6 +5,27 @@ module Grape
|
|
5
5
|
module Desc
|
6
6
|
include Grape::DSL::Settings
|
7
7
|
|
8
|
+
ROUTE_ATTRIBUTES = %i[
|
9
|
+
body_name
|
10
|
+
consumes
|
11
|
+
default
|
12
|
+
deprecated
|
13
|
+
description
|
14
|
+
detail
|
15
|
+
entity
|
16
|
+
headers
|
17
|
+
hidden
|
18
|
+
http_codes
|
19
|
+
is_array
|
20
|
+
named
|
21
|
+
nickname
|
22
|
+
params
|
23
|
+
produces
|
24
|
+
security
|
25
|
+
summary
|
26
|
+
tags
|
27
|
+
].freeze
|
28
|
+
|
8
29
|
# Add a description to the next namespace or function.
|
9
30
|
# @param description [String] descriptive string for this endpoint
|
10
31
|
# or namespace
|
@@ -49,58 +70,29 @@ module Grape
|
|
49
70
|
# # ...
|
50
71
|
# end
|
51
72
|
#
|
52
|
-
def desc(description, options =
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
elsif configuration.is_a?(Hash)
|
60
|
-
configuration
|
61
|
-
end
|
62
|
-
end
|
63
|
-
endpoint_configuration ||= {}
|
64
|
-
config_class = desc_container(endpoint_configuration)
|
73
|
+
def desc(description, options = nil, &config_block)
|
74
|
+
opts =
|
75
|
+
if config_block
|
76
|
+
desc_container(endpoint_configuration).then do |config_class|
|
77
|
+
config_class.configure do
|
78
|
+
description(description)
|
79
|
+
end
|
65
80
|
|
66
|
-
|
67
|
-
|
81
|
+
config_class.configure(&config_block)
|
82
|
+
config_class.settings
|
83
|
+
end
|
84
|
+
else
|
85
|
+
options&.merge(description: description) || { description: description }
|
68
86
|
end
|
69
87
|
|
70
|
-
|
71
|
-
|
72
|
-
options = config_class.settings
|
73
|
-
else
|
74
|
-
options = options.merge(description: description)
|
75
|
-
end
|
76
|
-
|
77
|
-
namespace_setting :description, options
|
78
|
-
route_setting :description, options
|
88
|
+
namespace_setting :description, opts
|
89
|
+
route_setting :description, opts
|
79
90
|
end
|
80
91
|
|
81
92
|
# Returns an object which configures itself via an instance-context DSL.
|
82
93
|
def desc_container(endpoint_configuration)
|
83
94
|
Module.new do
|
84
|
-
include Grape::Util::StrictHashConfiguration.module(
|
85
|
-
:summary,
|
86
|
-
:description,
|
87
|
-
:detail,
|
88
|
-
:params,
|
89
|
-
:entity,
|
90
|
-
:http_codes,
|
91
|
-
:named,
|
92
|
-
:body_name,
|
93
|
-
:headers,
|
94
|
-
:hidden,
|
95
|
-
:deprecated,
|
96
|
-
:is_array,
|
97
|
-
:nickname,
|
98
|
-
:produces,
|
99
|
-
:consumes,
|
100
|
-
:security,
|
101
|
-
:tags,
|
102
|
-
:default
|
103
|
-
)
|
95
|
+
include Grape::Util::StrictHashConfiguration.module(*ROUTE_ATTRIBUTES)
|
104
96
|
config_context.define_singleton_method(:configuration) do
|
105
97
|
endpoint_configuration
|
106
98
|
end
|
@@ -114,6 +106,19 @@ module Grape
|
|
114
106
|
end
|
115
107
|
end
|
116
108
|
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def endpoint_configuration
|
113
|
+
return {} unless defined?(configuration)
|
114
|
+
|
115
|
+
if configuration.respond_to?(:evaluate)
|
116
|
+
configuration.evaluate
|
117
|
+
# Within `given` or `mounted blocks` the configuration is already evaluated
|
118
|
+
elsif configuration.is_a?(Hash)
|
119
|
+
configuration
|
120
|
+
end
|
121
|
+
end
|
117
122
|
end
|
118
123
|
end
|
119
124
|
end
|
data/lib/grape/dsl/headers.rb
CHANGED
@@ -10,9 +10,9 @@ module Grape
|
|
10
10
|
# 4. Delete a specifc header key-value pair
|
11
11
|
def header(key = nil, val = nil)
|
12
12
|
if key
|
13
|
-
val ? header[key
|
13
|
+
val ? header[key] = val : header.delete(key)
|
14
14
|
else
|
15
|
-
@header ||=
|
15
|
+
@header ||= Grape::Util::Header.new
|
16
16
|
end
|
17
17
|
end
|
18
18
|
alias headers header
|
data/lib/grape/dsl/helpers.rb
CHANGED
@@ -33,18 +33,22 @@ module Grape
|
|
33
33
|
# end
|
34
34
|
#
|
35
35
|
def helpers(*new_modules, &block)
|
36
|
-
include_new_modules(new_modules)
|
37
|
-
include_block(block)
|
36
|
+
include_new_modules(new_modules)
|
37
|
+
include_block(block)
|
38
38
|
include_all_in_scope if !block && new_modules.empty?
|
39
39
|
end
|
40
40
|
|
41
41
|
protected
|
42
42
|
|
43
43
|
def include_new_modules(modules)
|
44
|
+
return if modules.empty?
|
45
|
+
|
44
46
|
modules.each { |mod| make_inclusion(mod) }
|
45
47
|
end
|
46
48
|
|
47
49
|
def include_block(block)
|
50
|
+
return unless block
|
51
|
+
|
48
52
|
Module.new.tap do |mod|
|
49
53
|
make_inclusion(mod) { mod.class_eval(&block) }
|
50
54
|
end
|
@@ -58,7 +62,7 @@ module Grape
|
|
58
62
|
|
59
63
|
def include_all_in_scope
|
60
64
|
Module.new.tap do |mod|
|
61
|
-
namespace_stackable(:helpers).each { |mod_to_include| mod.
|
65
|
+
namespace_stackable(:helpers).each { |mod_to_include| mod.include mod_to_include }
|
62
66
|
change!
|
63
67
|
end
|
64
68
|
end
|
@@ -94,7 +98,7 @@ module Grape
|
|
94
98
|
protected
|
95
99
|
|
96
100
|
def process_named_params
|
97
|
-
return
|
101
|
+
return if @named_params.blank?
|
98
102
|
|
99
103
|
api.namespace_stackable(:named_params, @named_params)
|
100
104
|
end
|